了解JavaScript中的原型

JavaScript是动态语言可以在任何时候向对象添加属性

function People(){
        this.name = 'JiaoMaiQi';
        this.gender = 'Male';
    }
    var peopleObj1 = new People();
    peopleObj1.age = 22;
    console.log(peopleObj1.age);            //22
    var peopleObj2 = new People();
    console.log(peopleObj2.age);           //undefined

age属性附加在peopleObj1实例上,而peopleObj2实例没有age属性,因为age属性只在peopleObj1上定义了,因此peopleObj2.age为undefined。那么,如果我们想添加一个属性并让这个属性被所有的实例共享,应该怎么办?答案就是:Prototype。

Prototype是一个对象,默认情况下与js中的任意一个函数或对象有关唯一的区别在于函数的prototype属性是可访问和可修改的,而对象的proto属性是不可见的。

默认情况下任何一个函数包含Prototype属性。

prototype对象是一种特殊类型的可枚举对象,可以将需要的附加属性添加到其上,这些属性将在其构造函数的所有实例之间共享。

那么,我们使用函数的prototype来添加age属性,以便于所有对象中都可以访问到:

 function People(){
        this.name = 'JiaoMaiQi';
        this.gender = 'Male';
    }
    People.prototype.age = 22;
    var peopleObj1 = new People();           
    console.log(peopleObj1.age);         //22
    var peopleObj2 = new People();
    console.log(peopleObj2.age);         //22

使用字面量或通过new关键字和构造函数的方式创建每一个对象都包含_proto_属性,该属性指向创建该对象的函数的原型对象。

 function People(){
        this.name = 'JiaoMaiQi';
        this.gender = 'Male';
    }
    //People.prototype.age = 22;
    var peopleObj1 = new People();
    console.log(People.prototype === peopleObj1._proto_);   //true

上面例子可以看出,函数通过函数名称.prototype方式访问到原型对象,但是对象实例并没有暴露出prototype属性,而是使用_prototype_来访问它。

Object对象的原型。

因原型对象在对象中是不可见的,因此使用Object.getPrototypeOf(obj)方法来访问实例的原型对象。

function People(){
        this.name = 'JiaoMaiQi';
        this.gender = 'Male';
    }
    var peopleObj = new People();
    People.prototype.sayHi = function () {
        console.log("Hi");
    }
    var peopleObj1 = new People();
    var proto = Object.getPrototypeOf(peopleObj1);     //return People's prototype object
    console.log(proto.constructor);                    //return People function

Object原型对象包含:属性、方法。

属性描述constructor 返回创建该实例的构造函数_proto_指向创建该实例的构造函数的原型对象。

修改原型。

每个对象都能链接到函数的原型对象。如果更改了函数的原型,则只有新对象将链接到更改后的原型。所有其他现有对象任然链接到旧的函数原型。下面实例来演示下:

 function People(){
        this.name = 'JiaoMaiQi';
        this.gender = 'Male';
    }
    People.prototype.age = 22;
    var peopleObj1 = new People();
    console.log('peopleObj1.age='+ peopleObj1.age);
    var peopleObj2 = new People();
    console.log('peopleObj2.age='+ peopleObj2.age);
    People.prototype = { age: 25 };
    var peopleObj3 = new People();
    console.log('peopleObj3.age='+ peopleObj3.age);
    console.log('peopleObj1.age='+ peopleObj1.age);
    console.log('peopleObj2.age='+ peopleObj2.age);

控制台输出如下:

使用原型。

原型被JavaScript引擎用来做两件事:

  • 查找对象的属性和方法
  • 在javascript中实现继承
 function People(){
        this.name = 'JiaoMaiQi';
        this.gender = 'Male';
    }
People.prototype.sayHi = function(){
     console.log("Hi");
}
var peopleObj = new People();
peopleObj.toString();

在上面实例中,toString()方法在People中并没有定义,那他是从哪里来的呢?

在这里,原型出现了。首先JavaScript引擎检查peopleObj是否含有toString()方法?如果没有,那么它会使用peopleObj的_proto_链接指向People函数的原型对象。如果仍旧没有找到,继续向上检查Object函数的原型对象,因为所有对象都是从JavaScrpt中的Object派生的。因此可以在object函数原型对象中找到toString()方法,因此可以调用peopleObj.toString()。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值