原型
概念
创建的每个函数都有一个prototype属性,该属性指向一个对象,这个对象就是原型对象。
构造函数,原型对象和实例对象的关系
// 声明一个构造函数
let Person = function( name,age) {
this.name = name
this.age = age
}
// 利用prtptype属性,将方法挂载到构造函数的原型对象上
Person.prototype.getName = function(){
return this.name
}
// 利用构造函数 创建一个实例对象
let p1 = new Person('Tom',20)
复制代码
- 构造函数有一个prototype属性,指向原型对象。
实例对象有一个__proto__属性,指向原型
都指向同一个对象,称为原型对象或者原型。
p1.__proto__ === Person.prototype // true
复制代码
- 原型对象的constructor属性 指向构造函数
Person.prototype.constructor === Person // true
复制代码
知识点补充:consructor属性
概念
每个实例对象都从原型继承了一个constructor属性,该属性指向了用于构造此实例对象的构造函数。
var o = {};
o.constructor === Object; // true
var a = [];
a.constructor === Array; // true
var a = new Array;
a.constructor === Array // true
var n = new Number(3);
n.constructor === Number; // true
复制代码
改变函数的constructor
大多数情况下,此属性用于定义一个构造函数,并使用new和继承原型链进一步调用它。
function Parent() {}
// 在父类的原型对象上挂载方法
Parent.prototype.parentMethod = function parentMethod(){}
function Child() {}
Child.prototype = Object.create(Parent.prototype)
Child.prototype.constructor = Child
复制代码
原型链
每个对象都有一个原型对象,对象以其原型为模板,从原型上继承方法和属性。
原型对象也可能拥有它自己的原型对象,并从中继承方法和属性,一层一层,依次类推。
这种关系被称为原型链。
可以使用in操作符检测一个属性是否在其对象或者其原型上。会顺着原型链进行查找。
可以使用instanceof检测对象的原型。
构造函数
概念
构造函数本质上也是常规函数,只不过有两个规定
语法
function User(name) {
this.name = name
}
// 使用构造函数
let user = new User()
复制代码
执行步骤
new操作符的执行步骤
实现一个new操作符
// 如何使用
// 1. 声明一个构造函数
let Person = function (name,age) {
this.name = name
this.age = age
this.getName = function(){
return this.name
}
}
// 2. 使用new操作符执行一个构造函数 创建实例对象
let p1 = new Person('Tom','age')
// 自己来实现一个new操作符 myNew
// new操作做的事情
// 1. 接收一个构造函数 作为参数, 返回一个对象
// 2. 声明一个中间对象,并最终返回这个对象
// 3. 将实例对象的原型指向构造函数的原型对象( 使用instanceof 能够检测到 对象的原型 )
function myNew(fun){
// 参数判断 是否是函数
// 声明一个中间对象 并最终返回它
let res = { }
// 执行一遍构造函数
fun.apply(res,Array.prototype.slice.call(arguments,1))
// 这句话做了什么?
// 1. fun使用apply方法,相当于以res这个对象的this,去执行了一遍fun这个构造函数
// 2. 由于构造函数可能需要多传参数,因此参数会保存在myNew这个函数的arguments里面,
// arguments是一个类数组,不可调用slice方法,这里借用数组的slice方法,对参数进行分割
// 剔除掉第一个参数,也就是fun,将剩余的参数,带入fun这个构造函数
//3. 修改 res对象的原型 指向
// 要先判断下 是否为 null
if(fun.prototype !== null){
res.__proto__ = fun.prototype
}
return res
}
let p1 = myNew(Person,'Tom',11)
// js内部再经过处理,
//将 let p1 = New(Person,'Tom',11) 等效于 let p1 = new Person('Tom', 11);
复制代码