一个while循环和“this”对象

时间:2014-07-28 00:33:55

标签: javascript loops prototype

下面的代码定义了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++;
}

说我打电话给&#34; findOwnerOfProperty&#34;对象上的方法:

newObject.findOwnerofProperty(firstProp);

我的问题是:

1)&#34;这&#34;会发生什么?循环运行时对象?

2)循环迭代究竟是什么?

3)第一个while循环和第二个while循环之间有什么区别,其中第二个循环有明显的增量,明确地改变了计数器&#39; x&#39;而第一个循环不?第一个代码的哪一部分改变了&#34; currentObject&#34;?

2 个答案:

答案 0 :(得分:2)

  

第一个while循环和第二个while循环之间有什么区别

第一个while循环是一个无限循环,因为currentObject永远不会改变。

答案 1 :(得分:1)

首先在对象本身上解析属性名称,然后在其[[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 会建议在那里找到该属性。

请注意, Object.getPrototypeOf 是ES5,因此并非在所有正在使用的浏览器中使用。

修改

可能会使用 this 的值调用该函数,而不是Object,例如:

bar.findOwnerOfProperty.call(null, 'bar');

期望的结果可能是未定义或者类型错误,但实际结果取决于代码是否严格以及提供的值。

非严格代码 -if 是一个原语,然后将其设置为将abstract ToObject运算符应用于原始值的结果(例如,如果它是一个数字,那么有效new Number(value),如果它是一个字符串,那么new String(value))。

对于 null undefined 设置为全局对象(请注意,应用 ToObject to null undefined 会抛出错误)因此将检查错误的继承链(即全局对象,而不是 null ),并且可能是将返回全局对象。

对于这两种情况的修复都是“RTFM”(好吧,如果有一个......),因为当执行任何代码时,这个已经设置好,并且无法检查原始调用

严格代码 - 在这种情况下, this 的值不会被修改,因此可以进行检查以确保它是对象或函数并返回 undefined < / em>否则:

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被转换为Number对象,就好像{{1在Number对象上调用 typeof ,返回new Number(7))。

为了实现一致性,对于 null undefined 以外的值,可以模拟 ToObject 运算符以获得严格的代码。或者,非严格版本只能在 typeof 返回 function object 的值上运行。我会把这个决定留给任何真正希望在愤怒中实现这一点的人。