原型链
1)定义对象的几种方法

结果打印:

2)原型链

① 只要是对象就是实例;
② new 函数 就叫做构造函数;
③ 函数在声明的时候都js会给一个属性prototype 指向原型对象
④
M.prototype.construct === M
obj3.__proto____ === M.prototype
obj3.constructor === M
⑤ Object.prototype是整个原型链的顶端
⑥ 如果我想增加一个say方法,可以直接在M方法上 this.say=function(){}增加,这样每个实例都会拷贝一份say方法,如果嫌占内存没必要,也可以在M的原型链增加,继而实例也是可以找到这个方法的。也就是说,任何一个实例对象通过原型链找到它上面的原型对象,原型对象上面的方法和属性都是被实例所共享的(原理)。

⑦只有函数有prototype 实例对象有__proto______,但是函数也有__proto______(因为它也是一个对象) M.__proto____ === Function.prototype 就是说 M的构造函数是Function 也可以说M这个普通的函数是构造函数Function的一个实例对象
3)instanceof
①左边 实例对象 instanceof 右边 构造函数
② 原理:判断这个实例对象是不是构造函数的实例,其实是 判断左侧实例对象的__proto____ 和 构造函数的prototype指向的是不是同一个引用 在同一条原型链上就可以

所以也可以说obj3是Object的实例 同一条原型链上都可以;
通过 obj3.__proto____.constructor === M | obj3.constructor === M; 通过constructor可以来精确的判断是不是哪个实例
4)new 运算符
new 关键字会进行如下操作:
1、创建一个空的JavaScript对象(即{});
2、将函数的 prototype 赋值给对象的 proto属性 ;
3、调用函数,并将步骤1新创建的对象作为函数的this上下文 ;
4、如果该函数没有返回值或者返回值不是对象,则返回创建的对象,如果返回值是对象,则直接返回该对象。
JS引擎执行这句代码时,在内部做了很多工作,用伪代码模拟其工作流程如下:
1 | new Person("John") = { |
相关文章:
https://juejin.im/post/5d65e03b6fb9a06b2c32a00c
https://juejin.im/post/5b397b526fb9a00e5d7999a4
继承
1)构造函数继承

打印结果:

这里可以看到,没有继承父类的say方法

原理:通过构造函数实现继承(call)
缺点:父类上的属性在构造函数里的都可以继承,但父类原型对象上的方法Parent.prototype 继承不到。
2)原型链继承

打印结果:

缺点:


总结: 当实例多个对象时,改变其中一个 另一个也改变。原因 这2个实例引用的原型对象是共用的。
3)组合方式

打印结果:

缺点:上图红色框中构造函数执行了2次,执行一次父类的属性子类已经有了
4)Object.create

上面代码中,Object.create 方法以A对象为原型,生成了B对象。B继承了A的所有属性和方法。
实际上,Object.create 方法可以用下面的代码代替.
1 | Object.create = function (obj) { |
上面代码表明,Object.create 方法的实质是新建一个空的构造函数 F ,然后让 F.prototype 属性指向参数对象 obj ,最后返回一个 F 的实例,从而实现让该实例继承 obj 的属性。
或者
1 | Object.create = function(obj){ |
或者
1 | Object.create = function(obj){ |
object.create方法生成的新对象,动态继承了原型。在原型上添加或修改任何方法,会立刻反映在新对象之上。
1 | var obj1 = { p: 1 }; |
上面代码中,修改对象原型obj1会影响到实例对象obj2。
Object.create 第一个参数
如果想要生成一个不继承任何属性(比如没有toString和valueOf方法)的对象,可以将
Object.create的参数设为 null。
1 | var obj = Object.create(null); |
Object.create 第二个参数
除了对象的原型,
Object.create方法还可以接受第二个参数。该参数是一个属性描述对象,它所描述的对象属性,会添加到实例对象,作为该对象自身的属性。
1 | var obj = Object.create({}, { |