我正在研究一个JavaScript项目,只是想知道为什么对象实例不继承defineProperty()和其他方法,而不是必须调用超类(superobject?)Object方法.
我查看了MDN文档,实际上有"非标准"属性方法.
但那些被弃用了.为什么要采取这些Object方法呢?
在我看来,像是instance.defineProperty(...)更好的东西Object.defineProperty(instance, ...).我也会对其他一些Object方法说同样的话.
Object.prototype.doSomething = function(p) {
this.innerHTML = "<em>bar</em>";
this.style.color = "#f00";
alert(p);
};
document.getElementById("foo").doSomething("Hello World");
Run Code Online (Sandbox Code Playgroud)
<div id="foo"><strong>foo</strong></div>
上面的代码工作正常.
但我记得我在某个地方看过这个:Do not mess with native Object.好吧,就像那样.
那么在Object上定义原型函数是否可以?我有什么理由不这样做吗?
在javascript中,可以"覆盖"属性或方法Object.prototype.例如:
Object.prototype.toString = function(){
return "some string";
};
Run Code Online (Sandbox Code Playgroud)
如果不仔细使用,它可能会破坏整个应用程序.是否有任何工具,技术或方法可以避免这种情况(例如,某种"严格模式"不允许开发人员覆盖Object的属性)?
我正在阅读MDN文档以更好地理解javascript.这是从那里的摘录
Object.prototype.objCustom = function() {};
Array.prototype.arrCustom = function() {};
let iterable = [3, 5, 7];
iterable.foo = 'hello';
for (let i in iterable) {
console.log(i); // logs 0, 1, 2, "foo", "arrCustom", "objCustom"
}Run Code Online (Sandbox Code Playgroud)
在最糟糕的情况下,我认为它将打印,0, 1, 2, "foo", "arrCustom"但它也打印objCustom.
更新:
1) 如何从可视化原型链iterable,以Array高达一路Object.就像有任何指向父母的iterable.getParent方法或iterable.myparent属性一样.
2)为什么它不打印数组函数,例如toString,sort它们也是打开的Array.prototype.
3)hasOwnProperty当有人向Array.prototype物业添加东西时,我是否需要始终使用?
我们都知道阵列上的for-in-loops 绝对是邪恶的.尽管如此,它们经常被使用,并且导致的错误很难追查,特别是当发生依赖浏览器时,例如因为indexOf-shims等.
所以,我编写了这个简单的代码段,它为" error"属性添加了一个可枚举的getter Array.prototype(不用于生产代码):
Object.defineProperty(Array.prototype, "error", {
enumerable: true,
get: function() {
if (this === Array.prototype) // that looks OK
return undefined;
if (window.confirm("Somebody who coded the site you're viewing runs through an Array with a for-in-loop.\nShame on him!\n\nDo you want to raise an Error to trace the origin?"))
throw new SyntaxError("Array traverse with for-in-loop, touching Array.prototype's 'error' property :-)");
}
});
Run Code Online (Sandbox Code Playgroud)
您可以将它添加为所有域的greasemonkey脚本,并且您将在几乎每个站点上看到警报:-)其中大多数是由调用jQuery.extend可疑参数引起的,顺便说一句.
我现在的问题是:是否有任何合理的"错误"循环或任何其他导致误报警报的情况?
我想知道这将如何影响我的代码的有用性.
我希望我的数组长度至少为 n。
如果元素数量低于给定长度,那么我希望用给定/默认元素填充它,直到长度为 n。
它非常像 String padEnd 函数。
a=[1,2,3]
a.padEnd(6, null);
a;// [1,2,3,null,null,null];
Run Code Online (Sandbox Code Playgroud)
到目前为止我的解决方案:
n = 10, value = {};
arr.concat(Array(n).fill(value, 0, n)).slice(0, n);
Run Code Online (Sandbox Code Playgroud) 我有一个API,我想断言至少返回预期的数据.我不在乎是否返回更多数据.
因此,我想比较两个对象(expected和actual),其中所有属性expected必须等于actual,但actual可能包含更多属性:
var expected = {
foo: 1,
bar: {
x1: 42,
a1: [
1,
2,
{
x: 7
}
]
}
}
var actual = {
foo: 1,
whatever: 55, // to be ignored
additional: { // to be ignored
ignore: 1
},
bar: {
x1: 42,
a1: [
1,
2,
{
x: 7,
y: 8 // to be ignored
}
]
}
}
partiallyEqual(expected, actual) // returns true …Run Code Online (Sandbox Code Playgroud) 通过解构可以很方便地从Objects 中提取属性:
let o = {id: "100", name: "Jane Doe", address: {id:1, city:"Fargo"}},
key = "address";
let {address: {id: id}} = o; // 1
Run Code Online (Sandbox Code Playgroud)
解构模式也可以计算:
let {[key]: {city: city}} = o; // Fargo
Run Code Online (Sandbox Code Playgroud)
但显然不可能动态提取嵌套对象的属性:
key = "address.city";
({[key]: city} = o); // undefined
Run Code Online (Sandbox Code Playgroud)
是否可以Object使用计算模式解构嵌套的 s?
这是我的代码:
const a = function(obj) {
for (let key in obj) {
if (!obj.hasOwnProperty(key)) {
continue;
}
console.info(key.split('_'));
}
};
a({a_b: 123});
Run Code Online (Sandbox Code Playgroud)
我认为没有任何问题,但SonarQube给了我一个严重的错误:
可以抛出TypeError,因为"key"可能为null或未定义.
字键在key.split("_")被高亮显示.这里指示变量键可以是undefined/null.
我试图传递类似的东西{[undefined]: 123},变量键变成一个字符串"undefined"而不是真正的undefined.
因此.我想知道在任何可能的情况下密钥都是undefined/null吗?还是只是假阳性?
这是一个截图:
如果我扩展Object原型并尝试使用jQuery 2.0.3的某些功能,我会收到错误...
Object.prototype.GetHashCode = function() { return 1; };
$(document).on("click", "div", function() { });
Run Code Online (Sandbox Code Playgroud)
如果我这样做,然后单击任何div我得到一个错误
Uncaught TypeError: Object function () { return 1; } has no method 'exec'
Run Code Online (Sandbox Code Playgroud)
为什么会这样?是否有解决方法或方法来解决jQuery中的这个错误?
我添加了一些有用的助手Array(比如toSource()Opera).现在for..in返回具有普通属性的函数.
我现在正在使用for..in,因为代码更易于阅读.它是js的原生功能,因此必须更快.
但是在循环中添加类型检查可以更容易地使用经典for(;;).
有没有什么方法可以避免for..in枚举函数?
跨浏览器工作不是很必要(必须在Opera中工作),但速度很重要.
谢谢.
编辑:
有没有能力避免for..in任何对象的枚举函数或自定义属性?
我总是不喜欢hasOwnProperty()在javascript中检查循环对象时的需要:
for ( var key in object ) {
if ( !object.hasOwnProperty( key ) ) {
continue;
}
// Now I can do whatever I needed to do
}
Run Code Online (Sandbox Code Playgroud)
它似乎总是浪费垂直空间来遍历对象中的键,然后必须明确检查以确保这些键不是来自其他地方.我显然很熟悉为什么这在javascript中是必要的,特别是由于旧的库有时会将东西注入原型链(咳嗽原型咳嗽).
但是,据我所知,棱角分明没有这样的东西.打字稿肯定没有理由.我无法想象任何现代的JavaScript框架会.因此,在现代Angular应用程序(或任何现代JavaScript应用程序)中跳过此类检查的可能缺点是什么.我只是冒着自己的团队意外修改原型(或意外导入修改原型的库)而导致问题的风险,还是有更多我不知道的麻烦空间?如果我尝试这样做,原型链会以什么其他方式咬我?
for ( let key in object ) {
}
Run Code Online (Sandbox Code Playgroud)
我自己的测试没有发现任何问题,但我可能会遗漏一些明显的东西.是的,我Object.keys( object )在mondern js/ts中知道.它完成了工作,但我不认为它像a一样干净for ... in,如果我能让它hasOwnProperty()死,我宁愿使用它.
javascript ×11
ecmascript-6 ×2
object ×2
angular ×1
ecmascript-5 ×1
function ×1
jquery ×1
loops ×1
nested ×1
opera ×1
prototype ×1
prototypejs ×1
sonarqube ×1
typescript ×1