Js Prototype简单的类型和对象

时间:2014-04-04 06:24:46

标签: javascript prototypal-inheritance

原型继承是否根据类型表现不同?在这两种情况下,上下文引用THIS是否有所不同?为什么在这个例子中,一个是访问原型而另一个是为对象创建一个新属性?

var Player = function(){};

Player.prototype.name = '';
Player.prototype.set_name = function(name){this.name = name;}

var p1 = new Player();
var p2 = new Player();

p1.set_name('Johanna');

这两个值的回报:

// Checking object properties
>p1
Player {name: "Johanna", set_name: function}

>p2
Player {name: "", set_name: function}

// Checking prototypes
>p1.__proto__
Object {name: "", set_name: function}

>p2.__proto__
Object {name: "", set_name: function}

但是,如果我使用名称作为对象属性执行播放器,则函数set_name正在修改原型。

var Player = function(){};

Player.prototype.name = {};
Player.prototype.set_name = function(name){this.name['first_name'] = name;}

var p1 = new Player();
var p2 = new Player();

p1.set_name('Andrew');

这两个值的回报:

// Checking object properties
>p1.name
Object {first_name: "Andrew"}

>p2.name
Object {first_name: "Andrew"}

// Checking prototypes
>p1.__proto__.name
Object {first_name: "Andrew"}

>p2.__proto__.name
Object {first_name: "Andrew"}

为什么会这样?我错过了哪些概念?

2 个答案:

答案 0 :(得分:2)

继承链

使用构造函数创建对象时,继承链如下所示,用于查找

  1. 将搜索当前对象。

  2. 将搜索父母的原型。

  3. 将搜索父母的父母的原型。

    ...

  4. 最后将搜索全局对象。如果在任何地方都找不到,则会返回undefined。如果在任何这些级别中找到要查找的值,它将立即返回。

    注意:分配不会上传继承链。如果为对象的属性赋值(如果它不存在则会创建),则该值将分配给该属性。

    第一种情况:

    你在做什么

    this.name = name;
    

    所以,

    p1.set_name('Andrew');
    

    name中创建新的p1属性,并在其中存储Andrew。当您尝试打印p1时,会在p1上查找该名称,并在p1本身找到该名称。所以,Andrew被退回了。但是,当您打印p2时,p2中找不到姓名。它在层次结构中上升并在父级原型中找到name。所以,它返回空字符串。

    第二种情况:

    你在做什么

    this.name['first_name'] = name;
    

    所以,

    p1.set_name('Andrew');
    

    name中查找p1。因为您尝试访问'first_name'上的this.name。因此,它尝试检索name属性。它在p1中找不到它,所以在父母的原型中找到它。它是一个空对象,name被分配给该对象的first_name属性。

    我们知道p2的原型与p1的原型相同。我们可以像这样确认

    console.log(p1.__proto__ === p2.__proto__);
    # true
    

    因此,当您查找与p2原型相同的p1原型时,会找到名称Andrew

答案 1 :(得分:0)

作为一般情况,变量等在构造函数中设置。 有关该主题的更多信息以及比我在此处可以参考的更好的解释:http://javascriptweblog.wordpress.com/2010/06/07/understanding-javascript-prototypes/

// Constructor
function Player() {
    this.names = '';
};

// Public Method
Player.prototype.set_name = function(name){
    this.name = name;
}

// Static method
Player.walk = function() {}

var player1 = new Player();
player1.set_name('John Doe'); // fires the public method
Player.walk(); // fires the static method