为什么在JavaScript中为实例变量声明属性

Dav*_*veM 25 javascript prototype this

我试图了解这种名为JavaScript的黑色艺术 - 而且,我必须承认,对此非常兴奋.我一直在寻找代码示例,主要来自"easeljs",因为这是我将主要使用的.我有点困惑..

我(我想)理解使用prototypefor函数或属性作为class变量和this.someProp用于'实例'变量之间的区别(是的,我知道JavaScript中没有类.)

我看过的代码,我用作自己代码的模板,declare prototype变量然后用它来引用它们

在构造函数中:

this.name = name;
Run Code Online (Sandbox Code Playgroud)

然后声明:

Object.prototype.name;
Run Code Online (Sandbox Code Playgroud)

然后,

this.name = "Freddy";
Run Code Online (Sandbox Code Playgroud)

这是在使用'new'调用的函数内,所以在这种情况下,据我所知,它this指的是当前对象.令我困惑的是原型声明正在做什么以及为什么我们将它用于实例变量?


澄清:在下面的代码中,我没有看到radius的原型声明实现了什么:

(function(){
    // constructor
    function MyCircle(radius){
        this.radius = radius;
    }
    MyCircle.prototype.radius;
    this.area = function(){
        return 3.14*this.radius*this.radius;
    };
    window.MyCircle = MyCircle;
}());
Run Code Online (Sandbox Code Playgroud)

Stu*_*eld 56

原型上的值具有与直接在实例上设置的属性不同的键行为.试试这个:

// Create a constructor
function A() {}

// Add a prototype property
A.prototype.name = "Freddy";

// Create two object instances from
// the constructor
var a = new A();
var b = new A();

// Both instances have the property
// that we created on the prototype
console.log(a.name); // Freddy
console.log(b.name); // Freddy

// Now change the property on the
// prototype
A.prototype.name = "George";

// Both instances inherit the change.
// Really they are just reading the
// same property from the prototype
// rather than their own property
console.log(a.name); // George
console.log(b.name); // George
Run Code Online (Sandbox Code Playgroud)

没有原型继承,这是不可能的.

您可以使用该hasOwnProperty方法测试属性是instance属性还是prototype属性.

console.log(a.hasOwnProperty("name")); // false
Run Code Online (Sandbox Code Playgroud)

实例可以覆盖该prototype值.

b.name = "Chris";
console.log(b.hasOwnProperty("name")); // true
console.log(a.name); // George
console.log(b.name); // Chris
Run Code Online (Sandbox Code Playgroud)

并回归prototype价值.

delete b.name;
console.log(b.hasOwnProperty("name")); // false
console.log(b.name); // George
Run Code Online (Sandbox Code Playgroud)

这是原型继承的有力部分.

在另一种模式:

function A() {
  this.name = "George";
}
Run Code Online (Sandbox Code Playgroud)

this.name每个新实例都会再次声明该变量.

将方法作为在原型上声明的函数是有道理的.所有实例都可以共享一个函数,而不是在每个实例上重新声明函数定义.

就变量而不是函数而言,在实例未设置其自己的值的情况下,原型可以用于默认值.

小提琴中的代码


Aln*_*tak 11

存储在原型上的值为该属性提供默认值.

如果您随后将值写入该属性,则实例将获取该新值,隐藏原型上的值,该值将保持不变.

在代码的上下文中,您现在已添加到问题中:

MyCircle.prototype.radius;
Run Code Online (Sandbox Code Playgroud)

什么都不做.这是一个无操作 - 它试图读取该属性然后丢弃结果.