文章目录
原型和原型链
prototype、 __ proto __ 、constructor
首先我们看下面一段代码
// 构造函数Person
function Person(name, age) {
this.name = name;
this.age = age;
this.sayHello = function () {
console.log('hello')
}
}
// 给Person的原型上挂载属性和方法
Person.prototype.sex = 'male'
Person.prototype.sayName = function () {
console.log(this.name);
}
// 实例化Person对象
const person1 = new Person('Jack', 20);
const person2 = new Person('Dave', 30);
console.log(person1.__proto__ === Person.prototype ) // true
console.log(person1.__proto__ === person1.__proto__) // true
console.log(Person.prototype.constructor === Person) // true
在这段代码中,共做了三件事
- 创建一个名为 Person 的构造函数,它接收 name、age 属性,同时 sayHello 方法
- 给构造函数 Person 的 prototype 挂载新的属性和方法
- 创建 Person 的实例对象 person1 person2
查看打印结果:
console.log(person1.__proto__ === Person.prototype ) // true
console.log(person1.__proto__ === person2.__proto__) // true
console.log(Person.prototype.constructor === Person) // true
结论
构造函数有一个prototype原型对象, 原型对象里的constructor指向构造函数本身
每个对象都有一个__proto__属性,并且指向它的构造函数的原型对象(prototype)
原型链
那么原型的存在到底有什么作用呢,其实就是一句话:对象不必存储所有的属性或方法,而可以通过原型层层向上查找,减少内存的占用
还是上面的例子,调用以下代码:
person2.sayHello() // hello
person2.sayName() // Dave
实例对象person2并没有直接定义方法sayName,但是它可以调用它的构造函数 Person 原型上的方法
接下来再加一行
console.log(person2.toString()) // "[object Object]"
打印的结果为 “[object Object]”,说明person2实例对象是存在这个方法的,但是person2本身和它的构造函数都没有定义 toString 方法,显然,它是在原型链上找到的:
这条绿色的线就是 原型链 :
- person2 实例对象本身没有toString方法,会顺着原型链找向它的构造函数Person的原型
- Person 对象本身也没有toString方法,会继续顺着原型链找向它的构造函数Object的原型
- 最终在Object的原型上找到了该方法,如果还没有找到,就会报null
原型方法
instanceOf
A instanceOf B 运算符用于检测A的原型链上是否存在构造函数B的 prototype属性,即
沿着A的原型链向上寻找,能否找到B
;能找到返回 true,否则返回 false。
const arr = new Array(['a','b','c'])
console.log(person1 instanceof Person) // true
console.log(person1 instanceof Array) // false
console.log(person1 instanceof Object) // true
console.log(arr instanceof Person) // false
console.log(arr instanceof Array) // true
console.log(arr instanceof Object) // true
原型链的终点指向Object,因此js中有一句话:万物皆对象
hasOwnProperty
A.hasOwnProperty(B) 判断对象 A 本身是否有属性或对象 B。有则返回true,没有返回false,此方法
不会沿着检查对象A的原型链寻找B
。
console.log(person1.hasOwnProperty('age')) // true
console.log(Person.hasOwnProperty('age')) // false
console.log(Object.hasOwnProperty('age')) // false
构造函数只有在实例化时才具备属性age
Object.create()、new Object()
- var B = Object.create(A) 返回一个新对象B, B的原型指向A, 即
B.__proto__ === A
。- var B = new Object(A) 则
B===A
const person3 = Object.create(person2)
const person4 = new Object(person2)
console.log(person3.__proto__ === person2, person3 === person2) // true false
console.log( person4 === person2) // true
当A为基本类型,var B = new Object(A)返回它本身,当A为空时,返回一个空对象
总结
原型和原型链
- prototype、 __ proto __ 、constructor
- 原型链
原型方法
- instanceOf
- hasOwnProperty
- Object.create()、new Object()