构造函数创建对象
Person和普通函数没有区别,之所以是构造函数在于它是通过new关键字调用的,p就是通过构造函数Person创建的实列对象
function Person(age, name) {this.age = age;this.name = name;}let p = new Person(18, '张三');
prototype
prototype n. 原型;雏形;最初形态
在JavaScript中,prototype属性是每个函数对象自带的一个属性,它是一个指针,在内存中保存的是这个对象的引用,指向一个对象,这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。当通过构造函数创建一个新的对象时,新对象内部会有一个内部属性([[Prototype]]),[[Prototype]]被设置为构造函数的prototype属性所指向的对象,也就是说jsp.__proto__ === Person.prototype
为true
构造函数与原型
当定义了一个函数并且打算用它作为构造函数来创建对象时,这个函数的prototype属性就变得很重要了,所有通过这个构造函数创建的对象都会共享prototype对象上的属性和方法
在构造函数的prototype属性上添加到属性和方法,所有由这个构造函数创建的对象实例都可以访问这些属性和方法
function Person(age, name) {this.age = age;this.name = name;}Person.prototype.say = function(){console.log(`i am ${this.name},age: ${this.age}`)}let p = new Person(18, '张三');let p1 = new Person(34, '李四');console.log(p,p1)console.log(p.say === p1.say)//true
原型链
JavaScript使用原型链实现了继承,每个对象都有一个内部链接到它的原型对象,而原型对象本身也是一个对象 ,也有自己的原型,这种链式关系一直持续到一个原型为null的对象为止,这标志着原型链的终点
__proto__与[[prototype]]与prototype
__proto__
:每个JavaScript对象都有的一个属性,它指向该对象的原型,它是一个访问器属性(getter/setter),它提供了对对象内部属性的访问,指向对象的原型
prototype:每个函数对象都有的属性,它指向一个对象,这个对象会被分配给所有通过这个函数创建的对象的__proto__
[[prototype]]:是每个对象内部的一个属性,指向该对象的原型
实例与原型
当在实例上寻找一个属性没找到时,就会查找与对象关联的原型中的属性,如果还查不到,就去找原型的原型,直到顶层为null为止
function Person(age, name) {this.age = age;this.name = name;}Person.prototype.say = function(){console.log(`i am ${this.name},age: ${this.age}`)}Person.prototype.a = 100let p = new Person(18, '张三');p.a = 'a property'console.log(p.a, 'first')delete p.aconsole.log(p.a,'second')
console.log(p.a, ‘first’)打印的a是字符串’a property’,因为这个属性存在于这个实例本身,console.log(p.a,‘second’)打印的a是100,因为上一句代码删除了实例的a属性,所以在这个实例本身是找不到的,所以会去这个实例的原型p.__proto__上找,找到了a属性,打印,如果没找到就到原型的原型上去找
原型的原型
打印的p.proto,可以看到对象的原型也是一个对象,既然是对象就可以通过new Object()的方式创建,其实原型对象就是通过Object构造函数生成的,而实例的__proto__指向构造函数的prototype
Object.getPrototypeOf()
返回指定对象的原型,所以就有
function Person(age, name) {this.age = age;this.name = name;}Person.prototype.say = function(){console.log(`i am ${this.name},age: ${this.age}`)}Person.prototype.a = 100let p = new Person(18, '张三');console.log(Object.getPrototypeOf(p) == Person.prototype)