JavaScript对象原型 JavaScript对象 原型JavaScript对象 原型

一、MDN上的解释(有点抽象)

基于原型的语言?

JavaScript 常被描述为一种基于原型的语言 (prototype-based language)——每个对象拥有一个原型对象,对象以其原型为模板、从原型继承方法和属性。原型对象也可能拥有原型,并从中继承方法和属性,一层一层、以此类推。这种关系常被称为原型链 (prototype chain),它解释了为何一个对象会拥有定义在其他对象中的属性和方法。

准确地说,这些属性和方法定义在Object的构造器函数(constructor functions)之上的prototype属性上,而非对象实例本身。

使用Javascript中的原型

在javascript中,函数可以有属性。 每个函数都有一个特殊的属性叫作原型(prototype)

MDN上解释的好抽象,看完之后感觉还是不知道原型是什么。

参考资料:MDN:对象原型

二、

JavaScript对象

JavaScript对象就是一组数据和功能的集合,除原始类型(string、number、boolean、null、undefined)之外,其余都是对象。 可以通过对象直接量(字面量)、new、和Object.create()(ECMAScript5)来创建对象。

//new
        var person = new Object();
        person.name = "YuanSong";
        person.age = 28;
        //对象字面量
      var person = {
            name : "YuanSong",
            age : 28
        };
       //Object.create()
       var person = Object.create({name : "YuanSong",
            age : 28});
       //{}
       var person = {};
       person.name = "YuanSong";
       person.age = 28;

原型

每一个JavaScript对象(null除外)都有原型,每一个对象都从原型继承属性。

所有通过对象字面量创建的对象都具有同一个原型对象,可以通过Object.prototype获得对原型对象的引用。

var person = {
            name : "YuanSong",
            age : 28
        };

        alert(Object.prototype.isPrototypeOf(person));           //true
        alert(Object.getPrototypeOf(person)==Object.prototype);  //true

通过关键字new和构造函数调用创建的对象的原型就是构造函数的prototype属性的值。

var dt=new Date();
alert(Date.prototype.isPrototypeOf(dt)); //true
alert(Object.getPrototypeOf(dt)==Date.prototype); //true
  function Person(){
        }
        
        Person.prototype.name = "YuanSong";
        Person.prototype.age = 28;
        Person.prototype.job = "Software Engineer";
        Person.prototype.sayName = function(){
            alert(this.name);
        };
        
        var person1 = new Person();
        var person2 = new Person();


        alert(Object.getPrototypeOf(person1)==Person.prototype);//true
        alert(Object.getPrototypeOf(person1).name);//YuanSong from prototype
        
        person1.name = "YuenSung";
        alert(person1.name);   //"YuenSung" from instance
        alert(person2.name);   //"YuanSong" from prototype

对实例对象属性的访问,首先读取实例对象的属性,如果没有在实例上发现该属性,则读取原型的属性,当为实例添加一个属性时,就会屏蔽原型对象中保存的同名属性,阻止访问原型中的那个属性,但不会修改原型的那个属性。

对象具有属性和方法,javascript中Object类型的实例都具有都具有以下属性和方法。

1 constructor:构造函数,保存着用于创建当前对象的函数(对于上面,Object())。

2 hasOwnProperty(propertyName):用于检查给定的属性在当前对象实例中是否存在(对于上面,person.hasOwnProperty("name"))。

3 isPrototypeOf(object):用于检查对象是否是传入对象的原型(对于上面,Object.prototype.isPrototypeOf(person))。

4 propertyIsEnumerable(propertyName):用于检查给定的属性能否使用for-in来枚举(对于上面,person.propertyIsEnumerable("name"))。

5 toLocalString():返回对象的字符串表示,与执行环境地区对应。

6 toString():返回对象的字符串表示。

7 valueOf():返回对象的字符串、数值或布尔值表示,通常与toString()方法返回值相同。

8 toJSON():JSON.stringify(person)=>"{\"name\":\"yuansong\",\"age\":28}"

参考JavaScript原型及原型链这篇文章很简洁清晰的写明了原型以及原型链的概念,一下子就明白了!!!

一、原型

原型是 ECMAScript 实现继承的过程中产生的一个概念。

继承

java 中:指在已有的一个类基础上创建新类的过程

ES:指在一个对象的基础上创建新对象的过程原型指在这过程中作为基础的对象。

二、prototype 属性

每一个实例对象,都有自己的属性和方法的副本。这不仅无法做到数据共享,也是极大的资源浪费。

prototype属性的引入

考虑到这一点,Brendan Eich 决定为构造函数设置一个 prototype 属性。

这个属性包含一个对象(以下简称” prototype 对象”),所有实例对象需要共享的属性和方法,都放在这个对象里面;那些不需要共享的属性和方法,就放在构造函数里面。

三、原型链

讲原型一个不可避免的概念就是原型链,原型链是通过前面两种创建原型的方式 Object.create() 或 DOG.prototype 时生成的一个 _proto_ 指针来实现的。

总结一下原型链作用:对象属性的访问修改和删除。

  1. 访问。优先在对象本身查找,没有则顺着原型链向上查找
  2. 修改。只能修改跟删除自身属性,不会影响到原型链上的其他对象。

四、总结

由于所有的实例对象共享同一个 prototype 对象,那么从外界看起来,prototype 对象就好像是实例对象的原型,而实例对象则好像”继承”了 prototype 对象一样。