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

IT技术 javascript browser
2021-01-27 00:22:56

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

输入:反映与正则表达式匹配的原始字符串的只读属性。

index:一个只读属性,它是字符串中匹配项的从零开始的索引。

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

6个回答

编辑:自从编写此答案以来,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

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

var myObject = {};
myObject.__defineGetter__("readOnlyProperty", function() { return 42; });

当然,这在网络上并不是很有用,因为它在 Internet Explorer 中不起作用。

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

对于您的实用程序,IE 从第 9 版开始支持此技术。这是一个很好的兼容性表:kangax.github.io/es5-compat-table
2021-03-19 00:22:56
它不是当前规范的一部分。我相信它计划用于 ECMAScript 的下一个版本,但现在,它只是一个 Mozilla 扩展,在其他一些浏览器中受支持。
2021-03-20 00:22:56
并且仍然不受 IE 支持;)
2021-03-21 00:22:56
附加说明 - 这是任何 javascript 规范的一部分吗?
2021-03-30 00:22:56
好一个!我测试过,它适用于 Firefox、Opera 和 Chrome,但不适用于 IE。
2021-04-02 00:22:56

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

来自ejohn.org 的示例

var obj = {};
Object.defineProperty( obj, "<yourPropertyNameHere>", {
  value: "<yourPropertyValueHere>",
  writable: false,
  enumerable: true,
  configurable: true
});
注意:这与 IE9+ 兼容,因此今天得到很好的支持
2021-04-11 00:22:56

JavaScript 中可能有只读属性,这些属性可以通过 getter 方法获得。这通常称为“module”模式。

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

这里是只读属性或变量。

正如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>

所以你有一个只读属性或变量测试。

我不敢相信这没有更多的赞成票。你知道它是如何工作的吗?
2021-03-18 00:22:56

是的,我们可以在 JavaScript 中为对象设置只读属性。它可以通过私有变量和object.defineProperty()方法来实现

请参阅以下示例,该示例说明了具有只读属性的对象,

function Employee(name,age){
    var _name = name;
    var _age = age;

    Object.defineProperty(this,'name',{
        get:function(){
            return _name;
        }
    })
}

var emp = new Employee('safeer',25);
console.log(emp.name); //return 'safeer'
emp.name='abc';
console.log(emp.name); //again return 'safeer', since name is read-only property