为什么不能重新定义财产?

时间:2017-05-18 16:07:15

标签: javascript ecmascript-6 ecmascript-5

当我运行以下代码时,我收到错误:

  

TypeError:无法重新定义属性:isBoolean

为什么我不能重新定义这些属性?



function isBoolean() {
  var value = arguments[0];
  if (!arguments.length) {return;}
  if (value===undefined || value===null) { return false; }
  if (typeof(value) === "boolean") {
    return true;
  } else {
    return false;
  }
}

function isString() {
  var value = arguments[0];
  if (!arguments.length) {return;}
  if (value===undefined || value===null) { return false; }
  if (typeof(value) === "string") {
    return true;
  } else {
    return false;
  }
}

function isNumber() {
  var value = arguments[0];
  if (!arguments.length) {return;}
  if (onoff) {
    if (value === Infinity) { return Infinity; }
  }
  if (value===undefined || value===null) { return false; }
  if (typeof(value) === "number") {
    return true;
  } else {
    return false;
  }
}

function isArray() {
  var value = arguments[0];
  if (!arguments.length) {return;}
  return Array.isArray(value);
}

Object.defineProperties(window, {
//  "thisType" : { enumerable: false },
  "isBoolean": { enumerable: false },
  "isString" : { enumerable: false },
  "isNumber" : { enumerable: false },
  "isArray"  : { enumerable: false },
});




3 个答案:

答案 0 :(得分:3)

因为全局函数声明在configurable标志为false的全局对象(浏览器上的窗口)上创建绑定。 GlobalDeclarationInstantiation中介绍了这一点,它使用CreateGlobalVarBinding为函数创建绑定,将false作为D标记传递,用于configurable旗。 (在步骤18.a中,函数名称是declaredVarNames的一部分,来自varDeclarations,通过VarScopedDeclarations检索,其中包含HoistableDeclaration个,其中一个这是FunctionDeclaration。)

由于绑定不可配置,因此您无法将其enumerable标记从true更改为false

答案 1 :(得分:1)

问题在于,当您在全局范围内声明一个函数时,它已经将它放在In [9]: import numpy as np In [10]: x = [[1,4,2,3,5],[3,5,2,1,3],[5,2,1,4,3],[1,2,3,5,4],[4,1,5,2,3]] In [11]: a = np.array(x) # Assumes all sublists are of the same length In [12]: np.argmax(a, axis=1) Out[12]: array([4, 1, 0, 3, 2]) 对象上,其可配置标志等于false 。避免这种情况的一种方法是定义另一个函数内部的函数(一个IIFE很好),如下所示:

您还应该在Object.defineProperties()内设置window对象的value属性,否则根据文档默认值为props

undefined

答案 2 :(得分:1)

由于您在问题中添加了ecmascript-6标记,我是否可以建议您将letconst与函数表达式一起使用?与函数声明/声明(大致表现为var)相反,使用let / const声明的全局变量/常量不会成为全局对象的属性(此处为window })。

const isBoolean = function () {
  var value = arguments[0];
  if (!arguments.length) {return;}
  if (value===undefined || value===null) { return false; }
  if (typeof(value) === "boolean") {
    return true;
  } else {
    return false;
  }
};

const isString = function () {
  var value = arguments[0];
  if (!arguments.length) {return;}
  if (value===undefined || value===null) { return false; }
  if (typeof(value) === "string") {
    return true;
  } else {
    return false;
  }
};

const isNumber = function () {
  var value = arguments[0];
  if (!arguments.length) {return;}
  if (onoff) {
    if (value === Infinity) { return Infinity; }
  }
  if (value===undefined || value===null) { return false; }
  if (typeof(value) === "number") {
    return true;
  } else {
    return false;
  }
};

const isArray = function () {
  var value = arguments[0];
  if (!arguments.length) {return;}
  return Array.isArray(value);
};

console.log('"window" properties before "defineProperties":');
console.log('isBoolean: ' + ("isBoolean" in window));
console.log('isString: ' + ("isString" in window));
console.log('isNumber: ' + ("isNumber" in window));
console.log('isArray: ' + ("isArray" in window));

Object.defineProperties(window, {
  "isBoolean": { enumerable: false },
  "isString" : { enumerable: false },
  "isNumber" : { enumerable: false },
  "isArray"  : { enumerable: false },
});

console.log('"window" properties after "defineProperties":');
console.log('isBoolean: ' + ("isBoolean" in window));
console.log('isString: ' + ("isString" in window));
console.log('isNumber: ' + ("isNumber" in window));
console.log('isArray: ' + ("isArray" in window));