标签: ecmascript-5

Object.preventExtensions实际上允许__proto__的变异?

我正在浏览MDC关于添加到Object的新功能.其中之一,Object.preventExtensions据说可以防止对象原型的突变,这可以通过使用Object.getPrototypeOf或获得__proto__.

然而,在Chrome上,它似乎只是允许突变到对象的原型.只需执行相关页面上的代码即可确认:

// EXTENSION (only works in engines supporting __proto__
// (which is deprecated. Use Object.getPrototypeOf instead)):
// A non-extensible object's prototype is immutable.

var fixed = Object.preventExtensions({});
fixed.__proto__ = { oh: "hai" }; // throws a TypeError
Run Code Online (Sandbox Code Playgroud)

我没有得到这个TypeError,fixed.__proto__.oh === 'hai'所以它已被设置,即使它应该被禁止.我也可以在编码时添加它Object.getPrototypeOf(fixed).oh = 'hai'.

这是否意味着Chrome对此功能有不同的解释?如何防止扩展对象的原型(在Chrome中)?

javascript object ecmascript-5 prototype-programming

4
推荐指数
1
解决办法
1826
查看次数

Array.prototype.forEach替代实现参数

在处理我最新的Web应用程序并需要使用该Array.forEach功能时,我经常发现以下代码用于添加对没有内置功能的旧浏览器的支持.

/**
 * Copyright (c) Mozilla Foundation http://www.mozilla.org/
 * This code is available under the terms of the MIT License
 */
if (!Array.prototype.forEach) {
    Array.prototype.forEach = function(fun /*, thisp*/) {
        var len = this.length >>> 0;
        if (typeof fun != "function") {
            throw new TypeError();
        }

        var thisp = arguments[1];
        for (var i = 0; i < len; i++) {
            if (i in this) {
                fun.call(thisp, this[i], i, this);
            }
        }
    };
}
Run Code Online (Sandbox Code Playgroud)

我完全理解代码的作用以及它是如何工作的,但是我总是看到它被复制,并且正式thisp参数被注释掉并将其设置为使用的局部变量arguments[1]. …

javascript ecmascript-5

4
推荐指数
1
解决办法
1162
查看次数

JavaScript eval("{}")返回行为?

根据ECMA-262规范,以下声明返回1:

eval("1;;;;;")
eval("1;{}")
eval("1;var a;")
Run Code Online (Sandbox Code Playgroud)

确保:

StatementList的值是StatementList中生成Statement的最后一个值的值.

你能解释这些不同的回报吗?

eval("{}") // undefined
eval("var a={}; a;") // {}
eval("var a={};") // undefined
Run Code Online (Sandbox Code Playgroud)

1;和之间有什么区别{};

javascript ecmascript-5

4
推荐指数
1
解决办法
168
查看次数

"this"对象的奇怪值

关于这段代码:

var name = "Jaguar";
var car = {
  name:"Ferrari",
  getName:function(){
    return this.name;
  }
};

alert((car.getName = car.getName)());
Run Code Online (Sandbox Code Playgroud)

输出是:Jaguar.

为什么this对象对应Windowcar变量中包含的对象而不是对象?

似乎将对象的函数重新分配给自身的事实导致在this调用函数时丢失对象的赋值...

我试图猜测:它是否存在一种机制(使用变量或其他),密切关注对象函数的非重新配置,以便在发生这种情况时,这种机制会阻止this关键字的分配.平常(因为等于对象)?

javascript function this ecmascript-5

4
推荐指数
2
解决办法
100
查看次数

Object.defineProperty polyfill

我目前正在编写一个基于ES5新功能的JavaScript API.它使用Object.defineProperty相当广泛.我把它包装成两个新的函数,叫做Object.createGetSetPropertyObject.createValueProperty

然而,我遇到了在旧浏览器中运行此问题的问题(例如可怕的IE8)

请考虑以下代码:

Object.createGetSetProperty = function (object, property, get, set, enumerable, configurable) {
    if (!Object.defineProperty) throw new Error("Object.defineProperty is not supported on this platform");
    Object.defineProperty(object, property, {
        get: get,
        set: set,
        enumerable: enumerable || true,
        configurable: configurable || false
    });
};

Object.createValueProperty = function (object, property, value, enumerable, configurable, writable) {
    if (!Object.defineProperty) {
        object[property] = value;
    } else {
        Object.defineProperty(object, property, {
            value: value,
            enumerable: enumerable || true,
            configurable: configurable || false,
            writable: …
Run Code Online (Sandbox Code Playgroud)

javascript ecmascript-5 es5-shim

4
推荐指数
1
解决办法
9202
查看次数

在Chrome中的冻结阵列上推送并弹出不会引发异常

以下代码似乎在Chrome下未按预期运行,并且在Firefox中运行方式不同.

(function () {
  'use strict';
  var
  arr = Object.freeze([1, 2, 3]);

  try {
    arr.push(4);
  } catch (e) {
    console.log(e);
  }

  try {
    console.log(arr.pop());
  }catch (e) {
    console.log(e);
  }

  console.log(arr);
})();
Run Code Online (Sandbox Code Playgroud)

我预计输出将是:

Error : (for `arr.push(4)`)
Error : (for `arr.pop()`)
[1, 2, 3]
Run Code Online (Sandbox Code Playgroud)

但是当在Chrome 29.0.1547.49(官方版本216092)beta-m上运行此代码时,我收到以下输出:

3
[1, 2, 3]
Run Code Online (Sandbox Code Playgroud)

为什么没有例外?我在Firefox Nightly 26.0a1(2013-08-12)上运行了这段代码,结果是

TypeError: arr.push(...) is not extensible
TypeError: property arr.pop(...) is non-configurable and can't be deleted
[1, 2, 3]
Run Code Online (Sandbox Code Playgroud)

正如我所料.

我想到了为什么Chrome和Firefox之间存在差异,然后我意识到这可能是因为严格的模式poppush方法.综上所述,在Firefox(SpiderMonkey)poppush方法中都是以严格模式定义的,但在Chrome(V8)中这些方法并没有在严格模式下定义.

我不知道实际的规格是什么.(我读了一些ECMA-262第5.1版,但我找不到这样的部分.)

javascript ecma262 ecmascript-5

4
推荐指数
1
解决办法
668
查看次数

ES6作为angularjs或angular2的打字稿目标编译器选项

我的angularjs应用程序的编译器选项如下。我应该使用其它软件包,transpile ES6ES5如果我更改了目标再次ES6

    {
      "compilerOptions": {
        "target": "es5", // Change this to es6
        "module": "commonjs",
        "sourceMap": true,
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "removeComments": false,
        "noImplicitAny": false,
        "outDir": "./wwwroot/app/"
      },
      "exclude": [
        "node_modules",
        "wwwroot"
      ]
    }
Run Code Online (Sandbox Code Playgroud)

ecmascript-5 angularjs ecmascript-6

4
推荐指数
2
解决办法
5428
查看次数

javascript中的裸对象是ECMAScript标准的一部分吗?

我遇到过这篇文章,建议如果你的密钥总是字符串,那么就需要使用'裸对象'来满足你的hashmap.

裸对象是使用null原型值创建的对象,例如Object.create(null).使用对象文字符号(即{})不会创建裸对象,因为它们被设置Object.prototype为原型.

文章指出裸机对象的优点是你可以将它们用作哈希映射,而不必担心内置键,比如toString在使用同名密钥时可能会导致错误.

这种行为是ES5和/或ES6标准的一部分吗?也就是说,如果我在代码中使用裸对象作为字符串键哈希映射,我可以依赖我的代码以我期望的方式运行吗?这里有什么警告吗?

javascript ecmascript-5 ecmascript-6

4
推荐指数
1
解决办法
471
查看次数

按ID数组对对象数组进行排序

是否可以很容易地通过ID数组对对象数组进行排序?这是一个例子:

[{
    id: "A",
    name: "John"
}, {
    id: "B",
    name: "Bobby"
}, {
    id: "C",
    name: "Peter"
}]
Run Code Online (Sandbox Code Playgroud)

现在,我有了一个对象数组,每个对象都有一个唯一的ID。然后,我有一个ID数组,如下所示:

var ids = ["C", "A", "B"];
Run Code Online (Sandbox Code Playgroud)

是否可以对对象数组进行排序,所以最终结果如下:

[{
    id: "C",
    name: "Peter"
}, {
    id: "A",
    name: "John"
}, {
    id: "B",
    name: "Bobby"
}]
Run Code Online (Sandbox Code Playgroud)

javascript arrays sorting ecmascript-5

4
推荐指数
1
解决办法
2920
查看次数

ES6到ES5:Babel实现类扩展

由于旧的浏览器支持,我们所有人都使用babeljs将ES6转换为ES5。当巴贝尔编译从另一类扩展的类。一部分已编译的代码与此类似:

...
if (superClass)
    Object.setPrototypeOf
      ? Object.setPrototypeOf(subClass, superClass)
      : (subClass.__proto__ = superClass);
...
Run Code Online (Sandbox Code Playgroud)

顶部代码块用于从父类延伸的静态属性。他们曾经Object.setPrototypeOf改变[[Prototype]]孩子的等级。它不是混淆.prototype[[Prototype]]是一个完全独立的东西。

MDN关于其使用的参考文献Object.setPrototypeOf如下:

根据现代JavaScript引擎如何优化属性访问的性质,更改对象的[[Prototype]]在每个浏览器和JavaScript引擎中的操作都非常缓慢。

我的问题出现在这里:如果我们可以通过Babel为什么使用另一种方式来达到相同的结果Object.setPrototypeOf?我试图通过遍历构造函数Function对象来从父类(我之前已为其分配)中复制所有静态方法。

...
if (superClass)
    Object.setPrototypeOf
      ? Object.setPrototypeOf(subClass, superClass)
      : (subClass.__proto__ = superClass);
...
Run Code Online (Sandbox Code Playgroud)

而且它比babel的执行速度还快!我创建了类似于babel扩展类的内容,并在jsPerf中对其进行了测试。我的前5个测试运行结果令人非常失望Object.setPrototypeOf:慢19%,慢20%和慢21%三倍。

我知道肯定还有一些原因,Object.setPrototypeOf可能需要使用。我想知道。如果是关于不可枚举的属性,那么我们绝对可以使用其他方法。

javascript ecmascript-5 ecmascript-6 babeljs

4
推荐指数
1
解决办法
363
查看次数