可以在纯JavaScript中实现只读属性吗?

Cla*_*diu 43 javascript browser

查看mozilla文档,查看正则表达式示例(标题为"使用匹配结果创建数组"),我们有以下语句:

input:一个只读属性,它反映与正则表达式匹配的原始字符串.

index:只读属性,是字符串中匹配的从零开始的索引.

etc ...是否可以在JavaScript中创建自己的对象,该对象具有只读属性,或者这是特定浏览器实现的内置类型的特权?

Mat*_*ley 64

编辑:由于这个答案是编写的,Object.defineProperty因此在EcmaScript 5中标准化了一种新的更好的使用方法,并支持更新的浏览器.见Aidamina的回答.如果您需要支持"较旧"的浏览器,您可以使用此答案中的一种方法作为后备.


在Firefox,Opera 9.5+和Safari 3 +,Chrome和IE(使用v11测试)中,您可以定义getter和setter属性.如果只定义一个getter,它会有效地创建一个只读属性.您可以在对象文字中定义它们,也可以通过调用对象上的方法来定义它们.

var myObject = {
    get readOnlyProperty() { return 42; }
};

alert(myObject.readOnlyProperty); // 42
myObject.readOnlyProperty = 5;    // Assignment is allowed, but doesn't do anything
alert(myObject.readOnlyProperty); // 42
Run Code Online (Sandbox Code Playgroud)

如果你已经有一个对象,你可以调用__defineGetter____defineSetter__:

var myObject = {};
myObject.__defineGetter__("readOnlyProperty", function() { return 42; });
Run Code Online (Sandbox Code Playgroud)

当然,这在Web上并不实用,因为它在Internet Explorer中不起作用.

您可以从John Resig的博客Mozilla开发人员中心了解更多相关信息.

  • IE仍然不支持;) (2认同)

Aid*_*ina 63

使用任何实现ECMAScript 5的javascript解释器,您可以使用Object.defineProperty来定义只读属性.在松散模式下,解释器将忽略对属性的写入,在严格模式下,它将抛出异常.

来自ejohn.org的示例:

var obj = {};
Object.defineProperty( obj, "<yourPropertyNameHere>", {
  value: "<yourPropertyValueHere>",
  writable: false,
  enumerable: true,
  configurable: true
});
Run Code Online (Sandbox Code Playgroud)

  • 注意:这与IE9 +兼容,所以今天更好[支持](http://kangax.github.io/compat-table/es5/). (2认同)

Rya*_*rty 6

可以在JavaScript中具有只读属性,这些属性可通过getter方法获得.这通常称为"模块"模式.

YUI博客有一篇很好的文章:http://yuiblog.com/blog/2007/06/12/module-pattern/

帖子的片段:

YAHOO.myProject.myModule = function () {

//"private" variables:
var myPrivateVar = "I can be accessed only from within YAHOO.myProject.myModule.";

//"private" method:
var myPrivateMethod = function () {
    YAHOO.log("I can be accessed only from within YAHOO.myProject.myModule");
}

return  {
    myPublicProperty: "I'm accessible as YAHOO.myProject.myModule.myPublicProperty."
    myPublicMethod: function () {
        YAHOO.log("I'm accessible as YAHOO.myProject.myModule.myPublicMethod.");

        //Within myProject, I can access "private" vars and methods:
        YAHOO.log(myPrivateVar);
        YAHOO.log(myPrivateMethod());

        //The native scope of myPublicMethod is myProject; we can
        //access public members using "this":
        YAHOO.log(this.myPublicProperty);
    }
};

}(); // the parens here cause the anonymous function to execute and return
Run Code Online (Sandbox Code Playgroud)


Ave*_*Gez 5

作为readonly属性或变量在这里.

正如aidamina所说,顺便说一句,这是一个简短的测试代码,现在JQuery假装弃用了选择器属性.

<script>
Object.defineProperties(window, {
  "selector": { value: 'window', writable: false }
});

alert (window.selector);  // outputs window

selector ='ddd';          // testing because it belong to the global object
alert (window.selector);  // outputs window
alert (selector);         // outputs window

window.selector='abc';
alert (window.selector);   // outputs window
alert (selector);          // outputs window
</script>
Run Code Online (Sandbox Code Playgroud)

所以你有一个readonly属性或变量测试.