我正在浏览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中)?
在处理我最新的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]. …
根据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;和之间有什么区别{};?
关于这段代码:
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对象对应Window于car变量中包含的对象而不是对象?
似乎将对象的函数重新分配给自身的事实导致在this调用函数时丢失对象的赋值...
我试图猜测:它是否存在一种机制(使用变量或其他),密切关注对象函数的非重新配置,以便在发生这种情况时,这种机制会阻止this关键字的分配.平常(因为等于对象)?
我目前正在编写一个基于ES5新功能的JavaScript API.它使用Object.defineProperty相当广泛.我把它包装成两个新的函数,叫做Object.createGetSetProperty和Object.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) 以下代码似乎在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之间存在差异,然后我意识到这可能是因为严格的模式pop和push方法.综上所述,在Firefox(SpiderMonkey)pop和push方法中都是以严格模式定义的,但在Chrome(V8)中这些方法并没有在严格模式下定义.
我不知道实际的规格是什么.(我读了一些ECMA-262第5.1版,但我找不到这样的部分.)
我的angularjs应用程序的编译器选项如下。我应该使用其它软件包,transpile ES6到ES5如果我更改了目标再次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) 我遇到过这篇文章,建议如果你的密钥总是字符串,那么就需要使用'裸对象'来满足你的hashmap.
裸对象是使用null原型值创建的对象,例如Object.create(null).使用对象文字符号(即{})不会创建裸对象,因为它们被设置Object.prototype为原型.
文章指出裸机对象的优点是你可以将它们用作哈希映射,而不必担心内置键,比如toString在使用同名密钥时可能会导致错误.
这种行为是ES5和/或ES6标准的一部分吗?也就是说,如果我在代码中使用裸对象作为字符串键哈希映射,我可以依赖我的代码以我期望的方式运行吗?这里有什么警告吗?
是否可以很容易地通过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) 由于旧的浏览器支持,我们所有人都使用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可能需要使用。我想知道。如果是关于不可枚举的属性,那么我们绝对可以使用其他方法。
ecmascript-5 ×10
javascript ×9
ecmascript-6 ×3
angularjs ×1
arrays ×1
babeljs ×1
ecma262 ×1
es5-shim ×1
function ×1
object ×1
sorting ×1
this ×1