引子
在平时写代码的时候,window对象使用是比较频繁的,而我在看框架源码的时候发现了有这种写法:
var root = typeof self == 'object' && self.self === self && self ||
typeof global == 'object' && global.global === global && global || this;
以上代码中,我们没有看到 window 对象的引用,而选择使用了self ,self 保存当前 window 对象的引用。
为什么使用self而不是使用window呢?而且”JS中还拥有self这个全局对象“有些小伙伴可能都不知道,那就让我们看看下面的内容:
在H5之前的window与self
在web页面环境下,默认下面这几种方案是等同的:
window.self === self // true
window.window === self // true
window.window === window.self // true
window = self // true
看到以上的情况后,window 与 self在多种情况下是相等的,那分开出现的意义是什么呢? 而真实情况其实是在H5之前,self的出场一般都是在当前页面有iframe嵌入的情况下,这样验证:
// true 表示作为iframe嵌入页面中,false 表示被iframe嵌入
parent === self
也可以这种理解:
在iframe内 self === parent // false,而主页面上是 self === parent // true
除此之外,在实际项目中基本没有什么出现的机会。
当然,这是在我们的HTML5新时代来临之前。而随着H5的新特性的到来,咱们的self对象摩拳擦掌、热泪盈眶,终于有了俺的用武之处。
self的春天:Web Worker、Service Worker
”众所周知的“,我们的Javascript脚本是单线程的,通俗一点就是可以叫做“窗体线程”。
主要是为了跟我们的浏览器窗口打交道。简单来说就是操作浏览器内的元素进行交互,所以我们可以使用window对象来获取想要的全局对象。
而Web Worker与Service Worker其实本质上是开启了另外的线程,而我们的Workers开启的新线程并没有所谓”窗体“这个概念。
这是浏览器”背着“我们悄咪咪的运行的线程,没有”窗体“意味着没有我们熟悉window对象,而这个时候:
我们的self就可以一脚踹开window, I can I up !
这时候在我们的Worker的上下文运行坏境中:self对象就变成了唯我独尊,window.self对象与window对象变成了局外人(不能使用),Web Worker栗子:
// 主线程
var worker = new Worker('work.js');
worker.postMessage('Hello World');
// Worker线程
self.addEventListener('message', function (e) {
self.postMessage('You said: ' + e.data);
}, false);
-
划重点:相比window,self 还能用于一些不具有窗口的上下文环境中,比如我们的双 Workers。所以,为了服务于更多场景,推荐使用更加通用的 self 对象。
-
新人写作,轻喷,欢迎指正。 Love and Peace .