Javascript对象的prototype

转帖: http://www.alloyteam.com/2015/10/prototype/?hmsr=toutiao.io&bsh_bid=928776428

最近恰好有人问起关于 javascript 中的 prototype 相关的问题。特此简单地整理了一下,比较基础,希望能让有类型问题的同学,可以用这篇文章提供参考。

prototype 是通过调用构造函数而创建的对象实例的原型对象。

  • 每一个新的函数,都会拥有一个 prototype 属性,这个属性指向函数的原型对象。
  • 所有原型对象都有一个 constructor 属性,指向了 prototype 属性所在函数的指针,即 Cat.prototype.constructor == Cat
  • prototype 对象是通过构造函数所产生的实例对象的原型对象,Cat.prototype.loveThing 为 prototype 添加属性,组成了这个prototype 对象。
  • 实例对象拥有一个指针 [[prototype]] 指向了它的原型对象 prototype。
function Cat(name){
    this.name = name;
}
Cat.prototype.loveThing = [‘apple‘];
Cat.prototype.sayHi = function(){
    alert(this.name);
}
var tomcat = new Cat(‘TOM‘);
tomcat.sayHi(); // TOM
tomcat.loveThing.push(‘orange‘);
alert(tomcat.loveThing); // apple,orange
var redcat = new Cat(‘RED‘);
tomcat.sayHi(); // RED
alert(redcat.loveThing); // apple,orange

可以看到,上面 tomcat 还有 redcat 作为 Cat 的实例,都 sayHi 出各自构造函数传入的 name。这并不奇怪。而 retcat 的loveThing 和 tomcat 一样,都是 apple,orange ?

当实例 tomcat 调用 tomcat.loveThing 的时候,由于实例中没有 loveThing 这个属性(与其原型对象相同),所以会继续向上搜索,读取到其原型对象的 loveThing 属性。此时执行的 tomcat.loveThing.push(‘orange’),相当于对原型对象进行操作,类似 Cat.prototype.loveThing.push(‘orange’);由于原型对象为所有对象实例 共用 。所以,后来执行了 redcat.loveThing,相当于执行了 Cat.prototype.loveThing;从而得到与 tomcat 相同的结果。

重写原型对象切断现有原型与任何之前已经存在的对象实例直接的联系,他们的引用仍然是最初的原型。

function Person(){};
var xiaoming = new Person();
Person.prototype = {
    constructor: Person,
    sayHi: function(){
        console.log(‘hi‘)
    }
}
xiaoming.sayHi(); // err

常用原型语法

function Cat(name){
    this.name = name;
}
Cat.prototype = {
    constructor: Cat,   //重新指向Cat
    sayHi: function(){
        console.log(this.name);
    }
}
var tomCat = new Cat();
console.log(tomCat instanceof Cat); // true
console.log(tomCat instanceof Object); //true 

上面代码重写了 Cat 的 prototype 属性,由于每一个 prototype 一个对应的 constructor 属性,所以此时 constructor 指向了 Object

console.log(tomCat.constructor == Cat); //true

当没有对 constructor 重新指向时,会出现下面的情况。

console.log(tomCat.constructor == Object); //true
console.log(tomCat.constructor == Cat); //false

for-in 与 hasOwnProperty()
由于 for-in 方法会将其实例还有原型的属性都输出,可以通过 hasOwnProperty() 这个方法来过滤出来自实例的属性

var obj = {name: 123}
for(var key in obj){
    if(Object.hasOwnProperty(key)){
        // ... 这些key来自实例,非来自原型。
    }
}
// 另: es5 中的 object.keys() 方法能够返回所有可枚举属性的字符串数组
时间: 2024-10-18 15:53:10

Javascript对象的prototype的相关文章

对于JavaScript对象的prototype和__proto__的理解

一.Object和Function的关系: 刚学JavaScript的时候,看书上说JavaScript中万物皆对象,而javascript中的其他对象都是从Object继承而来,包括内置对象.瞬间觉得Object碉堡了! 后来,又认识了Function,才知道原来Function才是隐藏在幕后的大BOSS,Object只不过是个大师兄. Object和Function都是JS自带的函数对象,Function比较牛逼点,因为它是Object的构造函数,而且Object的__proto__属性指向

javascript 对象 原型 prototype

关于js中object对象的prototype

我们都有一个误区,就是认为形成 Javascript 对象的prototype chain 的 prototype 就是一个名字为 prototype 的属性,而且是可以访问的.其实,Javascript 的 prototype 和 名字为 prototype 的属性在一开始一点儿关系都没有,是两个不同的事物. var Richard = new Object(); alert(typeof(Richard.prototype));  //undefined var Richard = new

15条规则解析JavaScript对象布局(__proto__、prototype、constructor)

大家都说JavaScript的属性多,记不过来,各种结构复杂不易了解.确实JS是一门入门快提高难的语言,但是也有其他办法可以辅助记忆.下面就来讨论一下JS的一大难点-对象布局,究竟设计JS这门语言的人当时是怎么做的?设计完之后又变成了什么? 我们来看一张图: 相信大家对这张图都不陌生了,构造函数有一个prototype属性指向其原型.相反原型也有一个constructor指向构造函数.与此同时实例也有一个constructor指向构造函数,这简直就是互相捆绑生怕找不到啊不是吗? 还有一个我们称之

javascript对象的属性,方法,prototype作用范围分析

读了篇博客感觉很有用"javascript对象的属性,方法,prototype作用范围分析"就自己写了一遍.以后自己可以用的到. 1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 2 <html xmlns="http://

为什么要设置Javascript对象prototype的constructor

最近读了一篇关于Javascript面向对象编程的文章,里面介绍了Javascript中的类,对象,属性,方法,构造函数,继承,封装,抽象和多态性.读完之后感觉受益匪浅,对Javascript有了进一步的认识.文章的地址在这里. 在讲到继承的时候,文章里面用了如下的例子 // define the Person Class function Person() {} Person.prototype.walk = function(){ alert ('I am walking!'); }; Pe

javascript--15条规则解析JavaScript对象布局(__proto__、prototype、constructor)

大家都说JavaScript的属性多,记不过来,各种结构复杂不易了解.确实JS是一门入门快提高难的语言,但是也有其他办法可以辅助记忆.下面就来讨论一下JS的一大难点-对象布局,究竟设计JS这门语言的人当时是怎么做的?设计完之后又变成了什么? 我们来看一张图:  相信大家对这张图都不陌生了,构造函数有一个prototype属性指向其原型.相反原型也有一个constructor指向构造函数.与此同时实例也有一个constructor指向构造函数,这简直就是互相捆绑生怕找不到啊不是吗? 还有一个我们称

[js高手之路]一步步图解javascript的原型(prototype)对象,原型链

我们接着上文继续,我们通过原型方式,解决了多个实例的方法共享问题,接下来,我们就来搞清楚原型(prototype),原型链的来龙去脉. function CreateObj(uName) {             this.userName = uName;         }         CreateObj.prototype.showUserName = function(){             return this.userName;         }         va

JavaScript中的面向对象编程,详解原型对象及prototype,constructor,proto,内含面向对象编程详细案例(烟花案例)

面向对象编程: 面向:以什么为主,基于什么模式 对象:由键值对组成,可以用来描述事物,存储数据的一种数据格式 编程:使用代码解决需求 面向过程编程: 按照我们分析好的步骤,按步骤解决问题 优点:性能比面向对象高,适合跟硬件联系很紧密的东西 缺点:没有面向对象那么容易维护,复用,扩展 面向对象编程: 把事务分解成一个个对象,然后由对象之间分工与合作,分工明确,每一个对象都是功能中心 面向对象特性:封装性.继承性 .多态性 封装性:将一个功能封装起来,小封装 将多个函数封装起来,整体封装起来形成一个