while循环和"this"对象
A while loop and the "this" object
下面的代码为Object的原型定义了一个自定义方法,该方法使用本机方法"hasOwnProperty"来查找传入属性的所有者。
Object.prototype.findOwnerOfProperty = function(propName){
var currentObject = this;
while (currentObject !==null){
if (currentObject.hasOwnProperty(propName)){
return currentObject;
}
}
}
我遇到的while循环通常是这样的格式:
while ( x < 10 ){
// do stuff
x++;
}
假设我在一个对象上调用了"findOwnerOfProperty"方法:
newObject.findOwnerofProperty(firstProp);
我的问题是:
1)当循环运行时,"this"对象发生了什么?
2)循环到底在迭代什么?
3)第一个while循环和第二个while循环之间的区别是什么,第二个循环有一个明显的增量,显式地改变计数器'x',而第一个循环没有?第一部分代码的哪一部分改变了"currentObject"?
第一个while循环和第二个while循环有什么区别
第一个while循环是无限循环,因为currentObject
永远不会改变。
属性名首先在对象本身上解析,然后在其[[Prototype]]
链上的对象上解析。您可以使用Object访问该链。getPrototypeOf,所以你可以这样做:
Object.prototype.findOwnerOfProperty = function(propName) {
var obj = this;
do {
if (obj.hasOwnProperty(propName)) {
return obj;
}
obj = Object.getPrototypeOf(obj);
} while (obj)
}
// Some tests
var obj = {foo:'foo'};
var x = obj.findOwnerOfProperty('foo');
console.log(x == obj); // true
// Find foo on Bar.prototype
function Bar(){}
Bar.prototype.foo = 'foo';
var bar = new Bar();
var p = Object.getPrototypeOf(bar);
console.log(bar.findOwnerOfProperty('foo') == Bar.prototype); // true
// Find toString on Object.prototpye
console.log(bar.findOwnerOfProperty('toString') === Object.prototype); // true
// Non-existant property
console.log(bar.fum); // undefined
console.log(bar.findOwnerOfProperty('fum')); // undefined
如果没有找到这样的对象,上面返回undefined,这似乎是合适的,因为null在所有[[Prototype]]
链的末尾,返回null表明在那里找到了该属性。
注意对象。getPrototypeOf是ES5的,所以不是在所有的浏览器中使用。
编辑
函数可能会以this不是Object的值调用,例如:
bar.findOwnerOfProperty.call(null, 'bar');
期望的结果可能是undefined或者可能是类型错误,但是实际结果取决于代码是否严格以及提供的值。
非严格代码 -如果这个是一个原语,那么它将被设置为对原语值应用抽象ToObject操作符的结果(例如,如果它是一个数字,那么有效地new Number(value)
,如果它是一个字符串,那么new String(value)
)。
在null和undefined的情况下,this被设置为全局对象(注意,将ToObject应用于null或undefined抛出错误),因此将检查错误的继承链(即全局对象,而不是null),并可能返回全局对象。
这两种情况的解决方案是"RTFM"(好吧,如果有的话…),因为在任何代码执行的时候,这个已经设置好了,不可能检查原始调用。
严格代码——在这种情况下,this的值没有被修改,因此可以进行检查以确保它是一个对象或函数,并返回undefined否则:
Object.prototype.findOwnerOfProperty = function(propName) {
var obj = this;
// Only applies to strict mode
if ((typeof obj != 'object' && typeof obj != 'function') || obj === null) return;
while (obj) {
if (obj.hasOwnProperty(propName)) {
return obj;
}
obj = Object.getPrototypeOf(obj);
}
}
所以对于严格模式和非严格模式可能会有不同的结果,例如
bar.findOwnerOfProperty.call(7, 'toString');
对于严格代码返回undefined,对于非严格代码Number(即Number构造函数)(因为7被new Number(7)
转换为Number对象,并且在Number对象上调用typeof返回'object'
)。
为了达到一致性,对于null和undefined以外的值,可以为严格的代码模拟ToObject操作符。或者,非严格版本只能对typeof返回函数或对象的值进行操作。我将把这个决定留给那些真正想在愤怒中实现这个的人。
- "“;变量未引用正确的对象
- 如何创建js常量对象与"依赖/相对;价值观
- "属性描述必须是对象“”;错误
- 获取"下一个“;对象中的数值
- 得到"TypeError:对象不是函数“”;在forEach循环中使用超级测试/超级代理时
- "键“;jQuery中的对象无法正常工作
- 为什么下面抛出一个“;对象没有't支持属性或方法'importNode'"在IE11中
- "未捕获[对象对象]”;投掷和接球时
- "对象不是函数“;当将Node.js HTTP服务器对象传递给Socket.IO时
- 将对象设置为Backbone.js模型,而不必调用“;set()"在每一处房产上
- 得到"未捕获的类型错误:未定义的不是函数“;当试图从对象调用get()或set()时
- 获得错误“;对象没有方法'jScrollPane'"与AngularJS一起使用时
- "类型错误:'null'不是对象(正在评估“a.nodeType')”;在phanto
- "这个“;对象函数内部的引用
- "对象没有't支持这种性质或方法“;在IE 8中.在调试中执行精细
- "Function.createDelegate"原因;错误:对象没有't支持属性或方法
- 在javascript中,使用requireJS,我如何"要求“;typescript对象
- a href="上的javascript对象对象;javascript:"呼叫
- TypeError:undefined不是一个对象(正在评估'msg.innerHTML="Uploa
- "[对象对象]”;类型为String