ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
## 构造函数 原型 实例 > 每个构造函数(constructor)都有一个原型对象(prototype),原型对象都包含一个指向构造函数的指针,而实例(instance)都包含一个指向原型对象的内部指针。 如果试图引用对象(实例instance)的某个属性,会首先在对象内部寻找该属性,如果查找不到,则会在该对象的原型(instance.__proto__)(下划线咋没了。。)里继续查找这个属性。 我们把这种搜索过程中,实例与原型的构成链条称作原型链。 ![](https://user-gold-cdn.xitu.io/2017/4/21/9609b9a345af595208b73b505ad167a6.png?imageView2/0/w/1280/h/960/format/webp/ignore-error/1) ## prototype 与__proto__ prototype 是只有函数才有的一个属性,指向函数的原型。 __proto__是对象的内部属性, 它指向构造器的原型, 对象依赖它进行原型链查询,instanceof 也是依赖它来判断是否继承关系.任何对象都有。 看一个例子: ~~~ function Person(name) { this.name = name; } var p1 = new Person('louis'); console.log(Person.prototype); //Person原型 {constructor: Person(name),__proto__: Object} console.log(p1.prototype); //undefined console.log(Person.__proto__); //空函数, function(){} console.log(p1.__proto__ === Person.prototype); //true ~~~ 从这里我们注意到一个问题, ~~~ Person.__proto__ === Function.prototype // true ~~~ 就是说可以说一般的构造器,都是继承于Function.prototype的。 那么Function.prototype是干什么的呢。 ## Function.prototype ~~~ console.log(typeof Function.prototype) // "function" console.log(Function.prototype.__proto__ === Object.prototype) // true ~~~ ## instanceof > instanceof 运算符用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性。 ~~~ [] instanceof Object // true [] instanceof Array // true ~~~ ## isPrototypeOf() > isPrototypeOf() 方法用于测试一个对象是否存在于另一个对象的原型链上。 ~~~ Object.prototype.isPrototypeOf([]) // true Array.prototype.isPrototypeOf([]) // true ~~~ ## 继承 #### es5的继承方式 只能继承父类实例的属性和方法,不能继承原型上的属性和方法。 ~~~ function Cat(name){ Animal.call(this); this.name = name || 'Tom'; } ~~~ **组合继承** 调用了两次父类构造函数,生成了两份实例 ~~~ function SuperType() { this.name = 'superType'; @@ -73,6 +89,20 @@ var instance2 = new SubType('hx'); console.log(instance2.colors); // ["red", "blue"] ~~~ 重点在于inheritPrototype函数 **寄生组合继承** ~~~ function Cat(name){ Animal.call(this); this.name = name || 'Tom'; } (function(){ // 创建一个没有实例方法的类 var Super = function(){}; Super.prototype = Animal.prototype; //将实例作为子类的原型 Cat.prototype = new Super(); })(); ~~~ #### es6的继承方式 ~~~ class superType { constructor (name) { this.name = name; } sayname() { console.log(this.name); } } class subType extends superType{ constructor (name) { super(name); } getname() { super.sayname(this.name); } } let obj = new subType('sky'); obj.getname(); // 'sky' ~~~ ## getPrototypeOf setPrototypeOf getPrototypeOf(obj):返回给定对象的原型 Object.setPrototypeOf(obj, prototype):分别为要设定的对象以及要设定原型为。 ## 遇到的题 1. 关于f可以有哪个属性的问题 ~~~ var F = function () { } Object.prototype.a = function () {} Function.prototype.b = function () {} var f = new F(); ~~~ 我们可以通过这段代码发现: ~~~ console.log(f.__proto__ === F.prototype); console.log(F.prototype.__proto__ === Object.prototype); console.log(F.__proto__ === Function.prototype); ~~~ f的继承链应是从 ~~~ f.__proto__ --->F.prototype.__proto__ ---> Object.prototype ~~~ 所以可以取到a 取不到b。