Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/33.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 属性已使用prototype更改,但在构造函数中未更改_Javascript_Prototype - Fatal编程技术网

Javascript 属性已使用prototype更改,但在构造函数中未更改

Javascript 属性已使用prototype更改,但在构造函数中未更改,javascript,prototype,Javascript,Prototype,如果我在prototype中操作一个属性,那么我只能通过prototype访问它。 当我在执行ninja.swing.swung时-使用ninja.prototype.swing时,poperty值发生了更改,但为什么在执行ninjaA.swung时我会变为true?不确定您预期会发生什么,但swung是一个特定于实例的成员,您可以使用特殊的this变量通过共享成员操纵它 即使您在Ninja.prototype上定义swung,默认情况下也会为true,但调用this.swung=false不会

如果我在prototype中操作一个属性,那么我只能通过prototype访问它。
当我在执行ninja.swing.swung时-使用ninja.prototype.swing时,poperty值发生了更改,但为什么在执行ninjaA.swung时我会变为true?

不确定您预期会发生什么,但swung是一个特定于实例的成员,您可以使用特殊的this变量通过共享成员操纵它

即使您在Ninja.prototype上定义swung,默认情况下也会为true,但调用this.swung=false不会更改Ninja.prototype.swung,因为赋值会导致在实例上创建swung,而不是查找原型链

因此,如果您希望通过实例更改共享成员并使其反映所有实例中的更改,则必须对共享成员进行变异。例如,您可以执行以下操作:

function Ninja(){
  this.swung = true;
}

var ninjaA = new Ninja();
var ninjaB = new Ninja();

Ninja.prototype.swing = function(){
  this.swung = false;
  return this;
};
console.log(ninjaA.swung,"checking Ninja's Swung member")//returning true WHY??
log( ninjaA.swing().swung, "Verify that the swing method exists and returns an instance." ); //false
log( !ninjaB.swing().swung, "and that it works on all Ninja instances." ); //true
bob.walk();ben.walk();
以下答案更详细地解释了这一点: 从上面的链接中解释从原型中变异共享成员的部分: 构造函数介绍

可以将函数用作构造函数来创建对象,如果构造函数名为Person,则使用该构造函数创建的对象是Person的实例

function Ninja(){
    // you want swung to be shared
    // instance specific members are defined here
//  this.swung = true;
}
Ninja.prototype.shared = {swung:true};
var ninjaA = new Ninja();
var ninjaB = new Ninja();

Ninja.prototype.swing = function(){
  this.shared.swung = false;
  return this;
};
console.log(ninjaB.shared.swung);//=true
ninjaA.swing();
console.log(ninjaB.shared.swung);//=false
Person是构造函数。使用Person创建实例时,必须使用new关键字:

var Person = function(name){
  this.name = name;
};
Person.prototype.walk=function(){
  this.step().step().step();
};
var bob = new Person("Bob");
属性/成员名称是特定于实例的,bob和ben的名称不同

成员walk是Person.prototype的一部分,并为所有实例共享。bob和ben是Person的实例,因此它们共享walk成员bob.walk===ben.walk

var bob = new Person("Bob");console.log(bob.name);//=Bob
var ben = new Person("Ben");console.log(ben.name);//=Ben
因为无法在bob上直接找到walk,JavaScript将在Person.prototype中查找它,因为这是bob的构造函数。如果在那里找不到它,它将在Object.prototype上查找。这被称为原型链。继承的原型部分是通过延长这个链来完成的;例如,bob=>Employee.prototype=>Person.prototype=>Object.prototype稍后将详细介绍继承

即使bob、ben和所有其他创建的Person实例共享walk,该函数在每个实例中的行为也会有所不同,因为在walk函数中,它使用了这一点。它的值将是调用对象;现在让我们假设它是当前实例,因此对于bob.walk,这将是bob。稍后将详细介绍这一点和调用对象

如果本在等红灯,鲍勃在等绿灯;然后你会调用本和鲍勃的步行,很明显,本和鲍勃会发生一些不同的事情

当我们执行ben.walk=22这样的操作时,会出现跟踪成员的情况,即使bob和ben共享walk将22分配给ben.walk不会影响bob.walk。这是因为该语句将直接创建名为walk on ben的成员,并将其赋值为22。将有两个不同的walk成员:ben.walk和Person.prototype.walk

在请求bob.walk时,您将获得Person.prototype.walk函数,因为在bob上找不到walk。但是,请求ben.walk会得到值22,因为成员walk是在ben上创建的,并且自从JavaScript在ben上找到walk之后,它将不会出现在Person.prototype中

更多关于原型的信息

一个对象可以通过use if prototype从另一个对象继承。可以使用object.create将任何对象的原型与任何其他对象一起设置。在构造函数介绍中,我们已经看到,如果在对象上找不到成员,JavaScript将在prototpe链中查找它

在前面的部分中,我们已经看到,重新分配来自实例原型ben.walk的成员将使该成员在ben上创建walk,而不是更改Person.prototype.walk

如果我们不重新分配,而是对成员进行变异怎么办?例如,变异是更改对象的子属性或调用将更改对象值的函数。例如:

function Ninja(){
  this.swung = true;
}

var ninjaA = new Ninja();
var ninjaB = new Ninja();

Ninja.prototype.swing = function(){
  this.swung = false;
  return this;
};
console.log(ninjaA.swung,"checking Ninja's Swung member")//returning true WHY??
log( ninjaA.swing().swung, "Verify that the swing method exists and returns an instance." ); //false
log( !ninjaB.swing().swung, "and that it works on all Ninja instances." ); //true
bob.walk();ben.walk();
下面的代码通过改变成员来演示原型成员和实例成员之间的差异

var a = [];
a.push(11);
a[1]=22;
上面的代码显示ben和bob共享person的成员。只有一个人,它被设置为bob的,ben的prototype person被用作prototype链中的第一个对象,用于查找实例上不存在的请求成员。上述代码的问题在于bob和ben应该有自己的food成员。这就是构造函数的作用。它用于创建特定于实例的成员。您还可以向它传递参数,以设置这些特定于实例的成员的值

下一段代码显示了实现构造函数的另一种方法,语法不同,但思想相同:

定义一个对象,该对象的成员在许多情况下都是相同的。person是bob和ben的蓝图,可以是jilly、marie、clair的蓝图。。。 定义实例特定的成员,这些成员对于实例bob和ben应该是唯一的。 创建一个实例 在步骤2中运行代码。 使用构造函数,您将在步骤2中设置原型。在下面的代码中,我们将在步骤3中设置原型

在这段代码中,我已经从prototype和food中删除了名称,因为无论如何,在创建实例时,您很可能会立即对此进行阴影处理。Name现在是特定于实例的成员,在构造函数中设置了默认值。因为food成员也从原型移动到了实例特定的成员,所以在向ben添加food时,它不会影响bob.food

var person = {
  name:"default",//immutable so can be used as default
  sayName:function(){
    console.log("Hello, I am "+this.name);
  },
  food:[]//not immutable, should be instance specific
         //  not suitable as prototype member
};
var ben = Object.create(person);
ben.name = "Ben";
var bob = Object.create(person);
console.log(bob.name);//=default, setting ben.name shadowed the member
                      //  so bob.name is actually person.name
ben.food.push("Hamburger");
console.log(bob.food);//=["Hamburger"], mutating a shared member on the
// prototype affects all instances as it changes person.food
console.log(person.food);//=["Hamburger"]
您可能会遇到类似的模式,这些模式在帮助创建对象和定义对象方面更加健壮

回归真为什么

因为这就是在构造函数中初始化它的方式

然后你调用.swing,它将swing设置为false,这有点违反直觉,但没关系。之后,您将按预期记录为false


它同样适用于你的忍者,尽管你已经反转了日志记录。swung==false,但是你记录了!ninjaB.swung.

你确定当你做ninjaA.swung时你是真的吗?你应该弄错了,我也弄错了,这是正确的行为。你打电话之前弄错了吗。在ninjaA上荡秋千?@Prasanna N我从ninjaA上荡秋千。你是如何变得松弛的。如果我想显示false,那么这个[ninjaA.swing.swung]语句requried@Bergi打电话给.swing后,我有一个更新问题,请参见注:这个问题似乎是受中的一个练习启发而提出的。如果我写这个[console.logninjaA.swung,检查忍者的swung成员],我期待这个问题出现然后我应该向我显示false,因为我通过调用原型内部的方法更改了这个属性,正如您在我的question@MohammadFaizankhan我会查看我答案中的链接。为实例成员指定值不会影响原型。变异来自原型的实例成员确实会影响原型。示例在链接中给出,但我会复制并粘贴到我的答案中。