企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
>[danger] 原型链继承 ***** 参考: 1. JS中所有对象都是Object的实例, Object是所有对象的父亲, 子类原型prototype指向父类实例对象实现继承 ``` Student.prototype = new Person(); ``` 2. 构造函数中, 使用call/apply实现继承, 子类构造函数中, 父类.call(this), 父类.apply(this), 作用是: 让Student内的this可以调用Person内的属性和方法 ``` function Student(){ // 区别: Person.call(this); // call(this,arg1, arg2, arg3 ) Person.apply(this); // apply(this, [arg1, agr2, arg3]) } Student.prototype = new Person(); ``` 扩展: 1. ES6 中引入了Class关键字, 转换成ES5以后其实是原型链继承 2. 每个new 出来的对象, 都拥有构造函数和prototype上的属性和方法, 也可以通过原型链去查找继承的属性/方法 3. 可以利用prototype给系统类扩展属性/方法 4. 原型继承方式, 子类实例化, 无法给父类传参, 但使用call可以给父类传参 ***** >[danger] new 都干了什么 ***** new 构造函数, 会让this指向一个全新Object对象, ``` var obj = {}; obj.__proto__ = Base.prototype; // 继承原型里属性/方法 Base.call(obj); // 继承构造函数里属性/方法 ``` ***** >[danger] prototype 和 __proto__区别? ***** 1. 方法/类拥有, `__proto__` 和 `prototype`, 对象拥有`__proto__` 2. __proto__解释: * 一个对象的__proto__指向它构造函数的prototype的值,这也保证了实例能够访问在构造函数和prototype中定义的属性和方法。 * 每个对象的__proto__属性, 是查找方法/类/对象的原型链方式. ``` // b.__proto__ == Boy.prototype 为true (证明1那句话是对的) // 原型的__proto__指向了它构造函数的prototype的值 ``` ***** 3. prototype 解释: (1) 方法除了__proto__还有prototype属性, 指向该方法的原型对象。 总结: a.__proto__指向A.prototype 指向 new Person() 原型对象 >[danger]看下面代码, 有什么问题? ~~~ function Person(){ this.name = "person"; this.grade = { math: 0 } } function Student() { } Student.prototype = new Person(); let stu1 = new Student(); stu1.name = "100"; stu1.grade.math = 100; let stu2 = new Student(); console.log(stu2.name); // name属性没有受到stu1的影响 console.log(stu2.grade.math); // 100 (很明显2个实例对象竟然共享了父类引用类型的数据 console.log(stu2.grade === stu1.grade); // true ~~~ 解决方式, 引入[组合继承](%E7%BB%84%E5%90%88%E7%BB%A7%E6%89%BF.md)