JavaScript进阶笔记(五):构造函数、原型和原型链
source link: https://www.tuicool.com/articles/uQjmyif
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
constructor
返回创建实例对象时构造函数的引用。此属性的值是对函数本身的引用,而不是一个包含函数名称的字符串。
构造函数和普通函数没有区别,不同点是构造函数使用 new 来生成实例对象,直接调用就是普通函数。
注意:构造函数首字母通常大写。
1.1 Symbol 是构造函数吗?
Symbol
是基本数据类型,他不支持 new Symbol()
操作。
生成 Symbol
实例直接使用 Symbol()
即可。
虽然不是构造函数,但可以获取到 constructor
属性值。
var sym = Symbol('sym') sym.constructor // ƒ Symbol() { [native code] }
这个 constructor
是哪里来的?其实是 Symbol
原型上的。 Symbol.prototype.construnctor
返回创建实例原型的函数。
1.2 constructor 值是只读的吗?
分为两种情况:属性值为基本数据类型是只读。属性值为引用类型是可以修改的。
可以直接对 constructor 进行赋值。
new
的实现:
function create() { // 1、创建一个空的对象 var obj = new Object(), // 2、获得构造函数,同时删除 arguments 中第一个参数 Con = [].shift.call(arguments); // 3、链接到原型,obj 可以访问构造函数原型中的属性 Object.setPrototypeOf(obj, Con.prototype); // 4、绑定 this 实现继承,obj 可以访问到构造函数中的属性 var ret = Con.apply(obj, arguments); // 5、优先返回构造函数返回的对象 return ret instanceof Object ? ret : obj; };
二、原型
JavaScript 是一种基于原型的语言 (prototype-based language),这个和 Java 等基于类的语言不一样。
每个对象拥有一个原型对象,对象以其原型为模板,从原型继承方法和属性,这些属性和方法定义在对象的构造器函数的 prototype 属性上,而非对象实例本身。
function Person () { this.name = 'owenli' this.age = 12 } Person.prototype.constructor === Person // true
构造函数有个指针指向原型,原型有个指针指向构造函数。
2.1 __proto__
在原型(Person.prototype)中有个 __proto__
属性,它是访问器属性。通过它可以访问内部的 [[Prototype]]
。 [[Prototype]]
是对象的内部属性,外部代码无法直接访问。
var p = new Person() p.__proto__ === Person.prototype // true
p.__proto__
可以直接访问到对象的原型, __proto__
是每个实例都有的属性。 prototype
是构造函数的属性。它们指向同一个对象。
注意: __proto__
是 ES6 的标准,兼容性问题和性能问题,推荐使用 Object.getPrototypeOf()
。考虑性能问题,避免修改 [[prototype]]
。
如果创建一个新对象,同时继承另一个对象的 [[prototype]]
,推荐用 Object.create()
。
优化 new 的实现:
function create() { // 1、获得构造函数,同时删除 arguments 中第一个参数 Con = [].shift.call(arguments); // 2、创建一个空的对象并链接到原型,obj 可以访问构造函数原型中的属性 var obj = Object.create(Con.prototype); // 3、绑定 this 实现继承,obj 可以访问到构造函数中的属性 var ret = Con.apply(obj, arguments); // 4、优先返回构造函数返回的对象 return ret instanceof Object ? ret : obj; };
三、原型链
每个对象拥有一个原型对象,通过 proto 指针指向上一个原型 ,并从中继承方法和属性,同时原型对象也可能拥有原型,这样一层一层,最终指向 null。这种关系被称为原型链 (prototype chain),通过原型链一个对象会拥有定义在其他对象中的属性和方法。
var p = new Person() p.constructor === Person
p
实例也有 constructor
,并不是。实例本身是没有 constructor
属性的,是通过原型链向上查找 __proto__
,最终查找到 constructor
属性,该属性指向 Person
。
p.constructor === Person //true p.__proto__ === Person.prototype //true p.__proto__.__proto__ === Object.prototype //true p.__proto__.__proto__.__proto__ === null // true
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK