原型与原型链

目录

原型

显式原型 prototype 

隐式原型 __proto__​(注意左右各是两个下划线)

显式原型与隐式原型的关系

hasOwnProperty() 方法

in 操作符

什么是原型链?


原型

原型是 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。

  • 26
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
原型原型链是 JavaScript 中的重要概念,用于实现对象的继承和属性访问。 在 JavaScript 中,每个对象都有一个隐式的属性__proto__,它指向该对象的原型(prototype)。原型是一个普通的对象,它包含共享的属性和方法。当我们访问一个对象的属性时,如果该对象本身没有该属性,JavaScript 引擎会沿着原型链向上查找,直到找到该属性或到达原型链的末尾。 原型链就是这种沿着__proto__指针链进行属性查找的过程。一个对象的原型可以通过 Object.getPrototypeOf() 方法获取。 当我们创建一个新的对象时,可以使用构造函数或者字面量来创建。构造函数可以通过使用 new 关键字来创建新的对象,并且每个构造函数都有一个 prototype 属性,该属性指向新创建的对象的原型。字面量创建的对象的原型是 Object.prototype。 通过设置构造函数的 prototype 属性,我们可以实现对象之间的继承。子对象将继承父对象原型上的属性和方法。当我们访问子对象的属性时,如果子对象本身没有该属性,会沿着原型链向上查找。 需要注意的是,原型链是一个单向的链式结构,如果在原型链上层级相同的位置存在同名属性,那么只会返回第一个找到的属性值。 总结起来,原型原型链是 JavaScript 中实现对象继承和属性访问的重要机制,通过原型链,我们可以共享属性和方法,并且实现对象之间的继承关系。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

橘子味的冰淇淋~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值