Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Js原型简单类型和对象_Javascript_Prototypal Inheritance - Fatal编程技术网

Javascript Js原型简单类型和对象

Javascript Js原型简单类型和对象,javascript,prototypal-inheritance,Javascript,Prototypal Inheritance,原型继承的行为是否因类型而异?在这两种情况下,上下文引用是否不同?为什么在本例中,一个访问原型,另一个创建对象的新属性 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');

原型继承的行为是否因类型而异?在这两种情况下,上下文引用是否不同?为什么在本例中,一个访问原型,另一个创建对象的新属性

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}
// 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"}
但是,如果我使用name作为对象属性处理播放器,那么函数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
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}
// 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"}

为什么会这样?我缺少什么概念?

作为一般情况变量,这些变量在构造函数中设置。 有关该主题的更多信息和更好的解释,请参见:


继承链

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

  • 将搜索当前对象

  • 将搜索父对象的原型

  • 将搜索父对象的父对象的原型

  • 最后搜索全局对象。如果在任何地方都找不到它,将返回未定义的
    。如果在这些级别中的任何级别中找到要查找的值,将立即返回该值

    注意:分配不会进入继承链。如果将值指定给对象的属性(如果不存在,则将创建该属性),则该值将指定给该属性

    第一种情况:

    你在干什么

    this.name = name;
    
    this.name['first_name'] = name;
    
    所以

    p1
    中创建一个新的
    name
    属性,并在其中存储
    Andrew
    。当您试图打印
    p1
    时,会在
    p1
    上查找该名称,并在
    p1
    本身中找到它。因此,
    Andrew
    被返回。但是,当您打印
    p2
    时,在
    p2
    中找不到名称。它在层次结构中向上移动,并在父对象的原型中查找
    名称
    。因此,它返回空字符串

    第二种情况:

    你在干什么

    this.name = name;
    
    this.name['first_name'] = name;
    
    所以

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

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

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

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

    当您向原型添加属性时,它将与其他实例共享。向构造函数添加唯一属性。不是Player.prototype.name='';和Player.prototype.name={};两者都使用原型吗?为什么在一种情况下使用set_name函数作用于原型,而在另一种情况下向对象添加属性?我了解了您在开头提到的继承链接。我知道,但你的留言是关键。谢谢