题目: 创建对象有几种方法?
- // 第一种方式: 字面量
- var o1 = {name: 'o1'};
- var o2 = new Object({name: 'o2'});// 也可以把这个放在下一类
- // 第二种方式: 构造函数
- var M = function (name) { this.name = name; };
- var o3 = new M('o3');
- // 第三种方式: Object.create()
- var p = {name: 'p'};
- var o4 = Object.create(p);
Object.create()方法会使用指定的原型对象及其属性去创建一个新的对象
o4 本身是一个空对象, 是不具备属性的, 它是通过原型链来链接它的原型对象的
构造函数 - 扩展
var a={}其实是 var a=new Object()的语法糖;
var a=[]其实是 var a=new Array()的语法糖;
funtion Foo(){...}其实是 var Foo=new Function()的语法糖;
原型构造函数实例原型链关系图
prototype 和__proto__的区别
prototype 是函数才有的属性 __proto__是每个对象都有的属性 (但是__proto__不是一个规范属性, 只是部分浏览器实现了此属性, 例如低版本的 IE 浏览器里面就没有实现) 大多数情况下,__proto__可以理解为构造器的原型, 即:__proto__ === constructor.prototype(通过 Object.create() 创建的对象不适用此等式, 其__proto__属性直接指向传入 Object.create()参数里面的那个对象)
什么是原型链?
由于__proto__是任何对象都有的属性, 而 js 里万物皆对象, 所以会形成一条__proto__连起来的链条, 递归访问__proto__必须最终到头, 并且值是 null 当 js 引擎查找对象的属性时, 先查找对象本身是否存在该属性, 如果不存在, 会顺着__proto__在原型链上查找, 但不会查找自身的 prototype
instanceof 原理
(1)判断实例对象里面的__proto__属性是否与构造函数里面的 prototype 属性指向的同一个地址
(2)在该原理里面, 这条原型链上的构造函数都是实例的构造函数 instanceof 都会返回 true
(3)example.__proto__.constructor===M: 用 constructor 来判断是否是某个构造函数的实例, 比用 instanceof 更加严谨
new 运算符原理
一个新对象被创建它继承自 foo.prototype 构造函数 foo 被执行执行的时候, 相应的参数会被传入, 同时上下文 (this) 会被指定为这个新实例 new foo 等同于 new foo(), 只能用在不传递任何参数的情况 如果构造函数返回了一个对象, 那么这个对象会取代整个 new 出来的结果如果构造函数没有返回对象, 那么 new 出来的结果为步骤 1 创建的对象
- var new2 = function (func) {
- var o = Object.create(func.prototype);
- var k = func.call(o);
- if (typeof k === 'object') {
- return k;
- } else {
- return o;
- }
- };
来源: https://www.2cto.com/kf/201803/727276.html