js基础七-- 原型、原型链
一、原型
实例对象中有__proto__这个属性,叫原型,也是一个对象,这个属性是给浏览器使用,不是标准的属性
构造函数中有prototype这个属性,叫原型,也是一个对象,这个属性是给程序员使用,是标准的属性
实例对象中__proto__指向的就是该实例对象中的构造函数中的原型对象prototype
构造函数中的prototype里面的属性或者方法,可以直接通过实例对象调用
原型:是function对象的一个属性,它定义了构造函数创建对象的公共祖先。通过该构造函数创建出的对象,可以继承该原型上的属性和方法,同时,原型也是对象。
原型的作用:数据共享、节省内存空间
(本身在构造函数中定义的属性和方法,当实例化(创建)对象的时候,实例对象中的属性和方法都是在自己空间中存在的,如果是多个对象,这些属性和方法都会在单独的空间中存在,浪费内存空间所以,为了数据共享,把想要节省空间的属性或者方法写在原型对象中,达到了数据共享,实现了节省内存空间。

下面代码在原型上定义了一个lasName属性,构造函数自身自带name属性,那么通过该构造函数创建的示例对象既可以访问构造函数自身内部的属性,也可以访问原型上的属性

如何查看原型:隐式属性 __ptoto__
对象如何查看对象的构造函数 construtor (对象.constructor 返回创建该对象的构造函数,这个构造器在构建该对象的构造函数的原型上)
二、原型链
原型链:是一种关系,实例对象和原型对象之间的关系是通过__proto__原型来联系起来的,这个关系就是原型链。其基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法。
如何构成原型链?
总结:
原型指向可以改变
实例对象的原型__proto__指向的是构建该对象的构造函数的原型对象
构造函数的原型对象(prototype)指向如果改变,实例对象的原型(__proto__)指向也会发生改变
实例对象和原型对象之间的关系是通过__proto__原型来联系起来的,这个关系就是原型链
三、构造函数和实例对象和原型对象之间的关系

构造函数,原型对象,实例对象之间的关系
1、实例对象通过构造函数创建(构造函数可以实例化对象)
2、有构造函数就有原型对象(构造函数中有一个属性prototype,是构造函数的原型对象,换言之,原型prototype对象是通过构造函数prototype属性(对象)生成 )
3、构造函数的原型对象(prototype)中有一个constructor构造器,这个构造器指向的就是自己所在的原型对象所在的构造函数
4、实例对象可通过__proto__原型共享prototype原型对象中的方法(方法在实例对象中不占据空间)(实例对象的原型对象__proto__指向的是该构造函数的原型对象prototype,构造函数的原型对象prototype中的方法是可以被实例对象直接访问的【共享】)

来看一些简单例子,了解原型之间的继承关系
案例1:

案例2:

案例3:


案例4:绝大多数对象的最终都会继承自Object.prototype(全部则是错的,原型的最终是null),所有函数的默认原型都是Object实例。

当以读取模式访问一个实例属性时,首先会在实例中搜索该属性。如果没有找到该属性,则会继续搜索实例的原型。在通过原型链实现继承的情况下,搜索过程就得以沿着原型链继续向上。
在找不到属性或方法的情况下,搜索过程直至末端才会停下来。
我们知道所有引用类型默认都继承了Object,而这个继承也是通过原型链实现的。
所有函数的默认原型都是Object的实例,默认原型都会包含一个内部指针,指向Object.prototype
案例5:原型上属性的增删改查

可以通过Object.create(原型)方法定义原型。例如:

注意:Object.create()括号中只能是对象或者null,否则会报错。
Object.prototype上的toString()方法,看下面例子:

四、确定原型和实例的关系
可以通过两种方式来确定原型和实例子之间的关系。
第一种是使用instanceof操作符,只要用这个操作符来测试实例与原型链中出现过的构造函数,结果就会返回true。由于原型链的关系,我们可以说instance 是 Object 、Super、Sub中任何一个类型的实例。
第二种是使用isPrototypeOf()方法。同样只要是原型链中出现过的原型,都可以说是该原型所派生的实例的原型,因此isPrototypeOf()方法也会返回true。
// 组合继承 function Super(name) { this.name = name; this.colors = ["red", "blue", "green"]; } Super.prototype.sayName = function() { console.log(this.name); } function Sub(name, age) { // 继承属性 Super.call(this, name); this.age = age; } // 继承方法 Sub.prototype = new Super(); Sub.prototype.sayAge = function() { console.log(this.age); } var instance = new Sub("james", 36); console.log(instance instanceof Sub); // true console.log(instance instanceof Super); // true console.log(instance instanceof Object); // true console.log(Object.prototype.isPrototypeOf(instance)); // true console.log(Super.prototype.isPrototypeOf(instance)); // true console.log(Sub.prototype.isPrototypeOf(instance)); // true
五、原型链继承的问题
过多的继承了没用的属性

浙公网安备 33010602011771号