做“Object(this)”的目的是什么?

我正在通过Array在MDN上find polyfill实现:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find?v=control#Polyfill

复制粘贴在下面:

  // https://tc39.github.io/ecma262/#sec-array.prototype.find if (!Array.prototype.find) { Object.defineProperty(Array.prototype, 'find', { value: function(predicate) { // 1. Let O be ? ToObject(this value). if (this == null) { throw new TypeError('"this" is null or not defined'); } var o = Object(this); // 2. Let len be ? ToLength(? Get(O, "length")). var len = o.length >>> 0; // 3. If IsCallable(predicate) is false, throw a TypeError exception. if (typeof predicate !== 'function') { throw new TypeError('predicate must be a function'); } // 4. If thisArg was supplied, let T be thisArg; else let T be undefined. var thisArg = arguments[1]; // 5. Let k be 0. var k = 0; // 6. Repeat, while k < len while (k < len) { // a. Let Pk be ! ToString(k). // b. Let kValue be ? Get(O, Pk). // c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)). // d. If testResult is true, return kValue. var kValue = o[k]; if (predicate.call(thisArg, kValue, k, o)) { return kValue; } // e. Increase k by 1. k++; } // 7. Return undefined. return undefined; } }); } 

为什么我们需要做var o = Object(this);

Object(this)实现了什么?

感谢您的任何讨论。

这是一个引人入胜的问题…感谢您的发布!

说实话,我对Object(this)有点惊讶,因为JavaScript似乎强制任何东西来对象(使用包装器)在this可能是一个原始值的情况下。

如果我们试图用Function.prototype.bind()来改变this ,JavaScript总是返回一个对象(一个函数是一个对象):

 var foo = function () { console.log(this, typeof this); }.bind('foo'); var bar = function () { console.log(this, typeof this); }.bind(1337); var baz = function () { console.log(this, typeof this); }.bind(false); var qux = function () { console.log(this, typeof this); }.bind(NaN); var quux = function () { console.log(this, typeof this); }.bind(undefined); var corge = function () { console.log(this, typeof this); }.bind(null); var grault = function () { console.log(this, typeof this); }.bind([]); var garply = function () { console.log(this, typeof this); }.bind({}); var waldo = function () { console.log(this, typeof this); }.bind(/regex/); var fred = function () { console.log(this, typeof this); }.bind(function () {}); foo(); // String { 0: "f", 1: "o", 2: "o" } object bar(); // Number { 1337 } object baz(); // Boolean { false } object qux(); // Number { NaN } object quux(); // Window object corge(); // Window object grault(); // Array [ ] object garply(); // Object { } object waldo(); // /regex/ object fred(); // function fred<() function 

如果我们试图用Function.prototype.call()Function.prototype.apply()来改变this ,那么JavaScript总是返回一个对象:

 Array.prototype.foo = function () { console.log(this, typeof this); }; ['foo'].foo(); // Array [ "foo" ] object Array.prototype.foo.call('bar'); // String { 0: "b", 1: "a", 2: "r"} object Array.prototype.foo.call(42); // Number { 42 } object Array.prototype.foo.call(true); // Boolean { true } object Array.prototype.foo.call(NaN); // Number { NaN } object Array.prototype.foo.call(undefined); // Window object Array.prototype.foo.call(null); // Window object Array.prototype.foo.call({}); // Object { } object Array.prototype.foo.call(/regex/); // /regex/ object Array.prototype.foo.call(function () {}); // function () function 

在JavaScript中,我们知道当本地对象不被用作构造函数而是作为常规函数时,本地对象可能对于types转换很有用。 NumberStringBoolean相当方便:

 var num = 1337, str = '', bool = true; console.log(Number(str), typeof Number(str)); console.log(Number(bool), typeof Number(bool)); console.log(String(num), typeof String(num)); console.log(String(bool), typeof String(bool)); console.log(Boolean(num), typeof Boolean(num)) console.log(Boolean(str), typeof Boolean(str)); 

在严格模式下,这个原语不会被强制转换为对象。

因此,使用Object(this)显式强制对象必要的。

这是一个更详细的例子:

 const array = Array.prototype; Object.defineProperty(array, 'foo1', { value() { return this.length >>> 0; }}); Object.defineProperty(array, 'foo2', { value() { "use strict"; return this.length >>> 0; }}); console.log(Array.prototype.foo1.call(undefined)); console.log(Array.prototype.foo2.call(undefined));