原型与原型链
目录
原型
原型是 JavaScript 继承的基础,JavaScript 的继承就是基于原型的继承。
显式原型 prototype
在 JavaScript 中,我们创建一个函数 A (就是声明一个函数),那么浏览器就会在内存中创建一个对象 B,而且每个函数都默认会有一个属性 prototype 指向了这个对象 B ( 即prototype 属性的值是这个对象 B)。这个对象B就是函数 A 的原型对象,简称函数的原型。这个原型对象 B 默认会有一个属性 constructor 指向了这个函数 A ( 意思就是说:constructor属性的值是函数 A )。
function A() {
console.log("Hello A")
}
console.log(A.prototype)
// {constructor: ƒ}
注意:prototype 是函数独有的属性,在对象上没有这个属性。
隐式原型 __proto__(注意左右各是两个下划线)
当把一个函数作为构造函数 (理论上任何函数都可以作为构造函数) 使用 new 创建对象的时候,那么这个对象就会存在一个默认的不可见的属性,来指向了构造函数的原型对象 prototype。 这个不可见的属性我们一般用 __proto__ 来表示。
注意:谷歌浏览器中,隐式原型 __proto__
的写法为:[[Prototype]]
function Person() {
this.name = 'Jasmine',
this.getName = function() {
console.log(this.name)
}
}
let person = new Person()
console.log(person.__proto__)
// {constructor: ƒ}
显式原型与隐式原型的关系
对象的隐式原型 __proto__
全等于构造函数的显示原型 prototype
function Person() {
this.name = 'Jasmine',
this.getName = function() {
console.log(this.name)
}
}
let person = new Person()
console.log(person.__proto__ === Person.prototype)
//true
hasOwnProperty() 方法
我们要去访问一个对象的属性的时候,这个属性既有可能来自对象本身,也有可能来自这个对象的 __proto__ 属性指向的原型对象。
那么如何判断这个对象的来源呢?
hasOwnProperty() 方法可以判断一个属性是否来自对象本身。
function Person() {
this.name = 'Jasmine',
this.getName = function() {
console.log(this.name)
}
}
Person.prototype.age = 27
let person = new Person()
console.log(person.hasOwnProperty('name'))
console.log(person.hasOwnProperty('age'))
console.log(person.hasOwnProperty('getName'))
// true
// false 因为 age 属性在原型对象 prototype 上
// true
hasOwnProperty() 方法可以判断一个属性是否来自对象本身。那如何判断一个属性是否存在呢?
in 操作符
in 操作符可以判断一个属性是否存在于这个对象中。只要对象和原型中有一个地方存在这个属性,就返回 true。
function Person() {
this.name = 'Jasmine',
this.getName = function() {
console.log(this.name)
}
}
Person.prototype.age = 27
let person = new Person()
console.log('name' in person)
console.log('age' in person)
console.log('getName' in person)
console.log('sex' in person)
// true 对象本身添加的
// true 原型中存在
// true 对象本身添加的
// false 对象和原型中都不存在
那如何判断一个属性是否存在原型中呢?如果一个属性存在,但是没有在对象本身中,则一定存在于原型中。
function propertyLocation(obj, prop) {
if (prop in obj) {
if (obj.hasOwnProperty(prop)) {
alert(`${prop} 属性存在于对象中`);
} else
alert(`${prop} 属性存在于原型中`);
}
} else {
alert(`${prop} 属性不存在`);
}
}
什么是原型链?
查找对象实例的属性和方法时,先在自身找,找不到则沿着 __proto__ 向上查找,直至 __proto__ 为 null,我们把 __proto__ 形成的链条关系称原型链(实现了js继承)。
用字符串调用字符串方法的时候,字符串会在 __proto__(
也就是 String()
构造函数)
寻找对应的字符串方法,字符串的__proto__ === String.prototype,如果 String()
构造函数没有该方法,那么 String()
会继续向上寻找,原型 prototype
是一个对象,那么对象就会有隐式原型 __proto__
,String()
的隐式原型 __proto__
是 Object()
,然后会在 Object()
的原型 prototype
上寻找,如果 Object()
的原型 prototype
上不存在该属性,那么就会通过隐式原型 __proto__
继续向上寻找,直到找到对应的方法为止,如果没有找到,那么就会报错,该方法不存在。
var str = ''
str.__proto__ === String.prototype
// true
str.__proto__ == String()
// true
String.prototype == String()
// true
str.__proto__
// String {'', constructor: ƒ, anchor: ƒ, at: ƒ, big: ƒ, …}
字符串、数组、构造函数的原型最终都会指向 Object
,而 Object
的原型指向的是 null。
原文地址:https://blog.csdn.net/m0_73531461/article/details/136739345
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!