编写用户脚本时,真的需要立即调用函数表达式(IIFE)模式吗? [英] Is the Immediately-Invoked Function Expression (IIFE) pattern really necessary when writing userscripts?

查看:127
本文介绍了编写用户脚本时,真的需要立即调用函数表达式(IIFE)模式吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题与用javascript自动执行功能的目的是什么?,但是它涉及用户脚本(专门用于GreaseMonkey).

My question is quite similar to What is the purpose of a self executing function in javascript?, however it concerns userscripts (specifically for GreaseMonkey) instead.

我看到有些用户脚本以这种模式分发,而有些则没有.

I see that some userscripts are distributed with this pattern, and some are not.

具有IIFE模式的脚本示例:(源)

Example of script with the IIFE pattern: (source)

// ==UserScript==
// (...)
// ==/UserScript==

(function(){
    // if <condition>
        document.location.href += '?sk=h_chr';
    // ...
})();

不带脚本的示例:(源)

// ==UserScript==
// (...)
// ==/UserScript==

window.location.href = "https://www.facebook.com/?sk=h_chr";

此外,我还发现TamperMonkey的"New script"模板紧随其后,而GreaseMonkey和ViolentMonkey的模板不遵循.

In addition, I also found that the "New script" template from TamperMonkey follows it, while the templates from GreaseMonkey and ViolentMonkey do not.

那么问题是,IIFE模式在编写用户脚本时是否有用?

The question is, then, is the IIFE pattern any useful when writing userscripts?

特别是,如果我的脚本处于 strict模式,并且我使用let而不是var.据我所知,无论如何,用户脚本中定义的函数和变量在全局页面范围中是不可用的.

Specially, if my script is in strict mode, and I use let instead of var. In any case, as far as I know, functions and variables defined in userscripts are not made available in the global page scope.

谢谢.

推荐答案

通常,不可以; IIFE模式对于包装整个用户脚本很少有用(请参见下面的边缘情况).这可以回溯到很多年前,当时某些引擎(简短地)默认情况下没有包装脚本.

In general, no; the IIFE pattern is seldom useful for wrapping a whole userscript (see edge cases below). That's a throwback to many years ago when some engines (briefly) did not wrap scripts by default.

实际上,如果您包含过时的 @unwrap指令,则该脚本引擎现在都将忽略它.

In fact, if you include the obsolete @unwrap directive, the script engines will all now ignore it.

以下是使用IIFE模式的一些原因:

Here are some reasons to use the IIFE pattern:

  • 这是目前整个脚本在 Violentmonkey (仅)中强制 c0>模式的唯一方法.但这只是对这台引擎的疏忽,希望能尽快得到纠正.
  • 如果同时使用以下两种功能,它可以无害 Parsing error: 'return' outside of function 警告:(1)脚本范围的return和(2)外部LINTer. br/> 一些旧的Greasemonkey版本也会对此发出警告,同时仍然可以正常运行.
  • (我以为是第三个边缘情况.但是被打断了,不记得是什么了.)
  • It is currently the only way to enforce strict mode in Violentmonkey (only) for the whole script. But this is an oversight for that one engine only and hopefully will be rectified soonish.
  • It can squelch a harmless Parsing error: 'return' outside of function warning if you use BOTH: (1) A script-wide return and (2) an external LINTer.
    Some old Greasemonkey versions would also warn about this, while still working perfectly.
  • (I thought there was a 3rd edge case. But got interrupted and can't remember what it was.)

考虑此测试脚本:

// ==UserScript==
// @name     _Scope and Strict-Mode Demo script
// @match    https://stackoverflow.com/*
// @unwrap
// @grant    none
// ==/UserScript==
/* eslint-disable no-multi-spaces, curly */
'use strict';

if (location.pathname.includes("/users/") ) {
    console.log ("Terminating script early.");
    return;  // In external LINTers, this will cause a harmless warning.
}

var cantSeeMeInConsole      = "neener neener";
window.canSomestimesSeeMe   = "Howdy";

console.log (`In Strict mode: ${bInStrictMode() }; \`cantSeeMeInConsole\`: ${cantSeeMeInConsole}`);

function bInStrictMode () {
    var inStrict = false;
    var dummyObj = {};
    Object.defineProperty (dummyObj, 'foo', {value: "bar", writable: false } );

    try { dummyObj.foo = "fee"; }
    catch (e) { inStrict = true; }
    return inStrict;
}

  • 在Firefox和Chrome上运行.
  • Safari和Opera应该给出相同的结果.
  • Microsoft Edge 可能给出相同的结果. (但我不在乎.)
  • 使用Tampermonkey,Violentmonkey和Greasemonkey 4运行.
    • Run on Firefox and Chrome.
    • Safari and Opera should give same results.
    • Microsoft Edge probably gives same results. (But I don't care much if it doesn't.)
    • Run using Tampermonkey, Violentmonkey, and Greasemonkey 4.
    • 在所有情况下,用户脚本都是作用域/包装的.该页面看不到代码,也看不到cantSeeMeInConsole之类的变量.
      请注意,脚本页面冲突仍可能在@grant none中发生模式.

      In all cases, the userscript is scoped/wrapped. The page can't see code, nor variables like cantSeeMeInConsole.
      Beware that script page conflicts can still occur in @grant none mode.

      应用其他隔离措施,具体取决于:(a)用户脚本引擎,(b)浏览器和(c)@grant模式.
      例如,使用Greasemonkey或更改授予模式会杀死页面查看canSomestimesSeeMe的能力.

      Additional isolations apply, depending on: (a) the userscript engine, (b) the browser, and (c) the @grant mode.
      For example, using Greasemonkey, or changing the grant mode kills the page's ability to see canSomestimesSeeMe.

      • 在Tampermonkey和Greasemonkey中,将'use strict';放在顶部,这样会将整个用户脚本切换为严格模式.
      • 这有点像Violentmonkey中不会发生的错误.
      • 此外,在Tampermonkey的高级选项中,您可以设置严格模式".所有脚本设置为[默认/始终/禁用].
      • In Tampermonkey and Greasemonkey, placing 'use strict'; up top like that switches the whole userscript into strict mode.
      • It's somewhat of a bug that this doesn't happen in Violentmonkey.
      • Additionally, in Tampermonkey's advanced options, you can set "strict mode" to [Default/Always/Disabled] for all scripts.

      在相关说明中,如果脚本不使用@run-at设置,则没有必要使用$(document).ready()或其简写.

      In a related note, if the script does not use @run-at settings, there is no point in using $(document).ready() or its shorthand.

      这篇关于编写用户脚本时,真的需要立即调用函数表达式(IIFE)模式吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆