Object.defineProperty或.prototype?

ban*_*tya 10 javascript string prototype object defineproperty

我已经看到了两种在javascript中实现非本机功能的不同技术,首先是:

if (!String.prototype.startsWith) {
    Object.defineProperty(String.prototype, 'startsWith', {
        enumerable: false,
        configurable: false,
        writable: false,
        value: function(searchString, position) {
            position = position || 0;
            return this.lastIndexOf(searchString, position) === position;
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

第二是:

String.prototype.startsWith = function(searchString, position) {
    position = position || 0;
    return this.lastIndexOf(searchString, position) === position;
}
Run Code Online (Sandbox Code Playgroud)

我知道第二个用于将任何方法附加到特定标准内置对象的原型链,但第一种技术对我来说是新的.任何人都可以解释它们之间的区别,为什么使用它们以及为什么不使用它们以及它们的意义是什么.

Sur*_*yan 16

在两种情况下,您要添加一个新属性'startsWith' String.prototype.

在这种情况下,第一个与第二个不同:

您可以配置成为财产enumerable,writable和configurable.

可写 -true表示您可以通过分配任何值来更改其值.如果为false - 您无法更改该值

Object.defineProperty(String.prototype, 'startsWith', {
        enumerable: false,
        configurable: false,
        writable: false, // Set to False
        value: function(searchString, position) {
            position = position || 0;
            return this.lastIndexOf(searchString, position) === position;
        }
    });

var test = new String('Test');

test.startsWith = 'New Value';
console.log(test.startsWith); // It still have the previous value in non strict mode
Run Code Online (Sandbox Code Playgroud)

可枚举 -true意味着它将在for in循环中被看到.

Object.defineProperty(String.prototype, 'startsWith', {
        enumerable: true, // Set to True
        configurable: false,
        writable: false, 
        value: function(searchString, position) {
            position = position || 0;
            return this.lastIndexOf(searchString, position) === position;
        }
    });

var test = new String('Test');

for(var key in test){
   console.log(key)  ;
}
Run Code Online (Sandbox Code Playgroud)

可配置 -true当且仅当可以更改此属性描述符的类型以及是否可以从相应对象中删除属性时.

Object.defineProperty(String.prototype, 'startsWith', {
            enumerable: false,
            configurable: false, // Set to False
            writable: false, 
            value: function(searchString, position) {
                position = position || 0;
                return this.lastIndexOf(searchString, position) === position;
            }
        });

    
    delete String.prototype.startsWith; // It will not delete the property
    console.log(String.prototype.startsWith);
Run Code Online (Sandbox Code Playgroud)

并且给你一个建议,不要改变构建类型的原型.

  • 你是对的。如果您将定义一个属性而错过了可写、可枚举和可配置的属性,则默认情况下它们的值将为“false” (2认同)