2

我也想吃蛋糕:我想有一个方法,this当它绑定到一个对象时返回链接,但undefined在使用 null|undefined 范围调用它时返回。这似乎工作正常,但如果你把它放到JSLint 中,那么你会得到一个 Strict Violation 错误。我不需要使用严格模式,但似乎这应该是可能的并且它有效(打开控制台)。这可以吗和/或你怎么能达到这个效果?

var o = {}; // or some pre-existing module
o.meth = (function (undefined) {

    // contrived example where you'd want to be able to locally 
    // access `meth` even if the outer `o.meth` was overwritten

    'use strict';

    var hash = Object.create(null); // "object" with no properties

    // global ref - or `null` where strict mode works
    var cantTouchThis = (function () {
        return this; 
    }).call(null);

    function meth (k, v) {
        var n;
        if (typeof k == 'object') { // set multi
            for (n in k) {
                meth(n, k[n]);
            }
        } else {
             if (v === undefined) { return hash[k]; } // get
             hash[k] = v; // set
        }
        if (this == cantTouchThis) { return; }
        return this;
    }

    return meth;

}());

如果您查看控制台:

var localM = o.meth; // now scopeless
console.log(  o.meth('key', 'val')  ); // should return `o`
console.log(  localM('key', 'val')  ); // should return `undefined`
4

2 回答 2

1

这几乎可以满足您的要求。

dontTouchThisnull在支持“使用严格”指令的环境中,并将在不支持它的环境中引用全局对象。

首先,你可以用;替换那个.call(null)块。(function(){return this})()它或多或少会产生相同的效果。

其次,不要忘记调用函数有 4 种方式,当涉及到this值时:作为方法、作为独立(无基础)函数、通过调用/应用和使用new运算符。这意味着:

  • new (o.meth)将返回o
  • o.meth.call(o2, ...)将返回o2
  • o.meth.call(null, ...)将返回undefined

最后,如果有人给全局变量取别名meth,那么在支持严格模式的环境meth()中将返回全局对象,而不是undefined因为cantTouchThis(being null) 不等于this(它将引用全局对象)。

// in global scope

var meth = o.meth;
meth(...); // `this` references global object, will return global object

(function() {

  // in local scope
  var meth = o.meth;

  meth(...); // `this` is `undefined`, will return `undefined`

})();
于 2012-09-01T22:02:40.463 回答
0

为了安全起见,我最终使用了一个本地函数来“接地”范围解析:

var gnd = (function () {
    var globe = this || window;
    return function (o) {
        // for grounding (securing) scope
        return o == null || o === globe ? 0 : o;
    };
}());

在此处查看源代码中的用法。

于 2012-09-14T01:48:28.293 回答