静态 javascript 成员 [英] Static javascript members

查看:38
本文介绍了静态 javascript 成员的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在使用它作为如何为我的对象声明静态成员的一个非常好的解决方法,但我真的不明白为什么它们会变成静态,所以我需要有人向我解释以下行为.

我有以下声明:

//原始所以这里没有什么有趣的Array.prototype.someMember = "我的值不是静态的";//包含原语的对象,现在是交易Array.prototype.someOtherMember = {价值:我的价值是静态的"};Array.prototype.changeMember = 函数(新值){//改变原始值this.someMember = newValue;//改变对象内部的原始值this.someOtherMember.value = newValue;};

如果通过以下方式进行测试:

var arr1 = [], arr2 = [], arr3 = [];arr1.changeMember('我改了');警报(arr1.someMember + ', ' + arr2.someMember + ', ' + arr3.someMember);警报(arr1.someOtherMember.value + ', ' + arr2.someOtherMember.value + ', ' + arr3.someOtherMember.value);

结果是:

<块引用>

我变了,我的价值不是一成不变的,我的价值不是一成不变的

我变了,我变了,我变了

现在,如果我像这样在 changeMember 方法中重新分配整个对象:

Array.prototype.changeMember = function (newValue) {//改变原始值this.someMember = newValue;//改变对象this.someOtherMember = { value: newValue };};

然后 someOtherMember 不再是静态的,而是 Array 的第一个实例获得它自己的.我不理解这种行为,因为毕竟我在这两种情况下都是通过 this 访问 someOtherMember,所以我无法弄清楚为什么它在第一种情况下是静态的,它是第二个不是静态的.

解决方案

JS 中没有静态属性这样的东西.您所看到的是原型继承的正常行为.关键概念是这样的:数组,实际上所有的对象,都是稀疏的一个实例没有属性,除非它被明确分配给那个实例.只要不发生这种情况,原型就拥有所有属性:

第一个案例
为什么你看到我变了,我的值不是静态的,我的值不是静态的?简单:当数组被实例化时,所有实例都会出现有一个名为someMember的属性,但实际上,它们没有.当您尝试访问 anArray.someMember 时,JS 将首先扫描该属性的实例,如果该实例没有定义该属性,则 JS 将转向原型并寻找 someMember 那里.在您的代码片段中,changeMember 方法使用 this 来引用调用该方法的实例,而不是 Object.getPrototypeOf(this).someMember.后者是在原型级别更改属性的方法.简而言之:

arr1.changeMember('我改变了');//与执行相同:arr1.someMember = '我改变了';arr1.someOtherMember.value = '我改变了';

someMember 的赋值是一个简单的赋值,即设置实例的属性.

第二种情况
第二个赋值是重新赋值一个对象的属性,它被Array.prototype.someOtherMember引用.对对象字面量的 Reference 不会改变,只会改变对象本身.就像在任何其他语言中一样:在处理引用时,对象可以随心所欲地改变,引用将保持不变(它的值可能会改变,但它的内存地址不会).
当您重新定义 changeMember 方法以将新的对象字面量 重新分配给属性时,您实际上是在创建与第一种情况相同的情况:直接分配将新对象分配给属性,这会导致 JS 扫描原型,而只是在实例级别分配属性.您可以使用 Object.getPrototypeOf(this) 或(对于旧浏览器)this.prototype:

Array.prototype.changeMember = function (val){this.someMember = '我在实例级别更改了';Object.getPrototypeOf(this).someMember = '重新分配原型属性为'+ val;Object.getPrototypeOf(this).someOtherMember = {value:val};//只改变proto};

话虽如此,如果您想要静态属性之类的东西,最好使用 Object.defineProperty:

Object.defineProperty(Array.prototype,'sortofStatic',{value:'我不能改变',writable:false,configurable:false});

更多示例 可以在 MDN 上找到

I have been using this for a while as a really nice workaround for how to declare static members for my objects but I really don't understand why they become static so I need somebody to explain to me the following behavior.

I have the following declarations:

// Primitive so nothing interesting here
Array.prototype.someMember = "My value is not static";
// Object containing a primitive, now this is the deal
Array.prototype.someOtherMember = {
    value: "My value is static"
};

Array.prototype.changeMember = function (newValue) {
    // Change the primitive value
    this.someMember = newValue;
    // Change the primitive value inside the object
    this.someOtherMember.value = newValue;
};

And if this is tested the following way:

var arr1 = [], arr2 = [], arr3 = [];
arr1.changeMember('I changed');
alert(arr1.someMember + ', ' + arr2.someMember + ', ' + arr3.someMember);
alert(arr1.someOtherMember.value + ', ' + arr2.someOtherMember.value + ', ' + arr3.someOtherMember.value);

The result is:

I changed, My value is not static, My value is not static

I changed, I changed, I changed

Now if I reassign the entire object in the changeMember method like this:

Array.prototype.changeMember = function (newValue) {
    // Change the primitive value
    this.someMember = newValue;
    // Change the object
    this.someOtherMember = { value: newValue };
};

Then someOtherMember is no longer static, but instead the first instance of Array gets its own. I don't understand the behavior because after all I am accessing someOtherMember through this in both cases, so I can't figure out why it's static in the first case and it's not static in the second.

解决方案

There's no such thing as a static property in JS. What you're seeing is the normal behaviour of prototypal inheritance. The key concept is this: Arrays, and indeed all objects, are sparse An instance doesn't have a property unless it's explicitly assigned to that instance. as long as that doesn't happen, the prototype holds all properties:

The first case
Why are you seeing I changed, My value is not static, My value is not static? Simple: When arrays are instantiated, all instances will appear to have a property called someMember, but in fact, they don't. When you try to access anArray.someMember JS will first scan the instance for that property, if that instance doesn't have that property defined, JS will turn to the prototype and look for someMember there. In your snippet the changeMember method uses this, to refer to the instance that invokes the method, not Object.getPrototypeOf(this).someMember. The latter being the way to change the property on the prototype level. In short:

arr1.changeMember('I changed');
// is the same as doing:
arr1.someMember = 'I changed';
arr1.someOtherMember.value = 'I changed';

The assignment to someMember is a straightforward assignment, setting a property of an instance.

The second case
The second assignment is reassigning a property of an object, that is referenced by Array.prototype.someOtherMember. The Reference to the object literal doesn't change, only the object itself. Just as in any other language: when dealing with references, the object can change as much as it likes, the reference will remain the same (its value might change, but its memory address doesn't).
When you redefine the changeMember method to reassign a new Object literal to a property, you're in essence creating the same situation as in case one: straightforward assignment of a new object to a property, that causes JS not to scan the prototype, but merely assign the property on an instance-level. You could use Object.getPrototypeOf(this) or (for older browsers) this.prototype:

Array.prototype.changeMember = function (val)
{
    this.someMember = 'I changed At instance level';
    Object.getPrototypeOf(this).someMember = 'Reassing prototype property to '+ val;
    Object.getPrototypeOf(this).someOtherMember = {value:val};//changes proto only
};

Having said that, if you want something like a static property, you're better of using Object.defineProperty:

Object.defineProperty(Array.prototype,'sortofStatic',{value:'I cannot be changed',writable:false,configurable:false});

More examples of this can be found on MDN

这篇关于静态 javascript 成员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆