__proto__(隐式原型)与prototype(显式原型)

题外话:先用构造函数构造一个实例对象

var log=console.log.bind(console)
function Person(){ //创建一个构造函数

}

var person1=new Person() //构造一个实例对象person1

person1.name='张三'

log(person1.name)//张三


// 每个函数都有一个prototype属性,这是函数特有的属性

Person.prototype.name='李四'

var person2=new Person()

log(person2.name)//李四

这个prototype就等于创建实例对象的原型也就是person1和person2的属性__proto__

每一个JavaScript对象(除了 null )都具有的一个属性,叫__proto__,这个属性会指向该对象的原型。

log(person1.__proto__===Person.prototype)//true
log(person2.__proto__===Person.prototype)//true

 

 

 

 

再看几个公式:

var 对象 = new 函数()
对象.__proto__ === 对象的构造函数.prototype

// 推论
var number = new Number()
number.__proto__ = Number.prototype


var object = new Object()
object.__proto__ = Object.prototype


var function = new Function()
function.__proto__ = Function.prototype

// 另外,所有函数都是由 Function 构造出来的,所以
Number.__proto__ = Function.prototype // 因为 Number 是函数,是 Function 的实例
Object.__proto__ = Function.prototype // 因为 Object 是函数,是 Function 的实例
Function.__proto__ == Function.prototye // 因为 Function 是函数,是 Function 的实例!

__proto__(隐式原型)与prototype(显式原型)的定义:

prototype:一个函数在创建之后都会拥有一个名为prototype的属性,这个属性指向以当前函数作为构造函数构造出来的对象的原型对象。

__proto:__是每个对象都有的一个属性

区别:

__proto__是每个对象都有的一个属性,而prototype是函数才会有(函数也有__proto__)的属性。

 

__proto__指向的是当前对象的原型对象,而prototype指向它的构造函数的原型对象。
 

作用:

1、肯定是为了继承!

 

2、prototype用来实现基于原型的继承与属性的共享。

 

3、__proto__就构成了我们常说的原型链,同样用于实现基于原型的继承。

 

关系:

当读取实例的属性时,如果找不到,就会查找与对象关联的原型中的属性,如果还查不到,就去找原型的原型,一直找到最顶层为止。

举个例子:

Person.prototype.name='李四'

var person2=new Person()

log(person2.name) //李四

person2.name='张三'

log(person2.name)//张三

delete person2.name

log(person2.name) //李四

如何原型上没有定义name属性呢,是不是就找不到了?

当然不是,因为原型也是一个对象,既然是对象就按对象分方式来查找。

 

请看:

1、f1和f2这两个对象的属性__proto__,指向构造函数(Foo)的原型对象(当前对象的原型对象)

 

2、构造函数Foo()原型属性Foo.prototype指向了原型对象(prototype指向它的构造函数的原型对象)

其它:

1、原型对象的__proto__指向它的构造函数的原型对象。

2、原型对象也有一个属性,叫做constructor,这个属性包含了一个指针,指回原构造函数。

// constructor

log(Person===person1.constructor)//true
log(Person===person2.constructor)//true

注意:上面的代码中person1和person2均没有constructor属性,它们会去Person的prototype上去找

log(Person.prototype.constructor===person2.constructor)//true

3、Object.prototype的__proto__属性指向null。

 

### JavaScript 原型机制详解 JavaScript 是一种基于原型的面向对象编程语言,其核心机制之一是**原型继承**。在 JavaScript 中,每个对象都有一个原型prototype),通过原型链实现属性和方法的继承。理解原型机制是掌握 JavaScript 面向对象编程的关键。 #### 显式原型 `prototype` 在 JavaScript 中,函数(Function)拥有一个特殊的属性 `prototype`,这是一个显式原型对象。每当通过该函数创建实例时,实例对象的隐式原型 `__proto__` 会指向该函数的 `prototype` 属性。这一机制允许实例共享函数原型上的属性和方法。 例如: ```javascript function Person(name) { this.name = name; } Person.prototype.sayHello = function() { console.log(`Hello, ${this.name}`); }; const person1 = new Person('Alice'); person1.sayHello(); // 输出: Hello, Alice ``` 在上述代码中,`sayHello` 方法定义在 `Person.prototype` 上,所有 `Person` 的实例(如 `person1`)都可以访问该方法,因为它们的 `__proto__` 指向 `Person.prototype` [^1]。 #### 隐式原型 `__proto__` 每个对象(包括函数)都有一个 `__proto__` 属性,它是一个指向其构造函数原型对象的引用。这个属性是对象在创建时自动关联的,用于实现原型链的查找机制。 例如: ```javascript console.log(person1.__proto__ === Person.prototype); // true ``` 在 JavaScript 中,对象在访问某个属性或方法时,如果自身没有定义该属性,则会沿着 `__proto__` 向上查找,直到找到该属性或到达原型链的末端(即 `null`)[^3]。 #### 原型对象对象原型的关系 原型对象prototype)是函数的一个属性,而对象原型(__proto__)是对象实例的一个属性。两者的关系是:对象实例的 `__proto__` 指向其构造函数的 `prototype`。 例如: ```javascript function Foo() {} const foo = new Foo(); console.log(foo.__proto__ === Foo.prototype); // true ``` 这表明对象 `foo` 的原型是 `Foo.prototype` [^5]。 #### 原型链Prototype Chain) 原型链是指对象通过 `__proto__` 属性链接到其原型对象,而原型对象本身也可能有 `__proto__`,从而形成一条链式结构。原型链的终点是 `null`。 例如: ```javascript function Animal() {} Animal.prototype.eat = function() { console.log('Animal eats'); }; function Dog() {} Dog.prototype = Object.create(Animal.prototype); Dog.prototype.bark = function() { console.log('Dog barks'); }; const dog = new Dog(); dog.eat(); // 输出: Animal eats dog.bark(); // 输出: Dog barks ``` 在这个例子中,`Dog` 的原型是通过 `Object.create(Animal.prototype)` 创建的,因此 `dog` 实例的 `__proto__` 指向 `Dog.prototype`,而 `Dog.prototype` 的 `__proto__` 指向 `Animal.prototype`,从而形成一条原型链 [^4]。 #### 继承机制 JavaScript 的继承机制依赖于原型链。当访问一个对象的属性或方法时,JavaScript 引擎会首先检查对象自身是否有该属性。如果没有,则会沿着 `__proto__` 查找,直到找到匹配的属性或方法,或者到达原型链的末端(`null`)。 例如: ```javascript const obj = {}; console.log(obj.toString()); // 输出: [object Object] ``` 在这个例子中,`obj` 没有定义 `toString` 方法,但它继承自 `Object.prototype`,因此可以通过原型链访问该方法 [^3]。 #### `instanceof` 运算符 `instanceof` 用于判断一个对象是否是某个构造函数的实例。其判断依据是检查对象的原型链中是否包含构造函数的 `prototype`。 例如: ```javascript console.log(person1 instanceof Person); // true console.log(person1 instanceof Object); // true ``` 这表明 `person1` 是 `Person` 和 `Object` 的实例,因为 `Person.prototype` 的 `__proto__` 指向 `Object.prototype` [^4]。 #### 总结 JavaScript原型机制通过 `prototype` 和 `__proto__` 实现对象之间的继承关系。每个对象都有一个 `__proto__`,指向其构造函数的 `prototype`,而 `prototype` 是函数的一个属性,用于定义实例共享的属性和方法。原型链则是通过 `__proto__` 的链接形成的继承结构,最终以 `null` 结束。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值