每天一个npm包:object-is

467 阅读2分钟

es-shims/object-is这个库主要是作为ES6 Object.is()的垫片。通过阅读这个库,了解了两个概念的区别:shims、polyfill。

shims vs polyfill

关于什么是polyfill?推荐阅读。

shims理解它就是一个库,它将一个新的API引入到一个旧环境,并且在旧环境中仅通过旧环境API就完成相应功能实现。比如$.ajax的shims就封装了XMLHttpRequest与ActiveXObject两种方式的实现。此外shims是不区分环境的,只要JS引擎支持运行代码即可。

polyfill属于shims一种,你可以理解它为浏览器环境下的shims。因此polyfill最主要用途就是:检测浏览器是否支持某一个 API,如果不支持就加载一个 polyfill;如果支持,就是用浏览器的原生API,这样就可以让开发者在任何情况下无缝的使用那些 API 了。

源码

关于define-property可以阅读下面文章

'use strict';

var define = require('define-properties');
var callBind = require('call-bind');

var implementation = require('./implementation');
var getPolyfill = require('./polyfill');
var shim = require('./shim');

var polyfill = callBind(getPolyfill(), Object);

define(polyfill, {
	getPolyfill: getPolyfill,
	implementation: implementation,
	shim: shim
});

module.exports = polyfill;

我们看看shims.js下Object.is的处理。

'use strict';

var getPolyfill = require('./polyfill');
var define = require('define-properties');

module.exports = function shimObjectIs() {
	var polyfill = getPolyfill();
        // 如果Object.is(原生)与polyfill不一致时候,即使用自定义的polyfill版本
	define(Object, { is: polyfill }, {
		is: function testObjectIs() {
			return Object.is !== polyfill;
		}
	});
	return polyfill;
};

polyfill.js

'use strict';

var implementation = require('./implementation');

module.exports = function getPolyfill() {
        // polyfill一般就是干这个活
        // 如果支持原生API、则使用原生API、否则不支持就自己实现一个
	return typeof Object.is === 'function' ? Object.is : implementation;
};

implementation.js

通过下面代码,我们也可以了解如果实现一个Object.is。

'use strict';

// 判断是否是NaN、只有NaN与自身不全等
var numberIsNaN = function (value) {
	return value !== value;
};

module.exports = function is(a, b) {
        // 就是处理了两个特殊场景、其他与“===“一致
        // -0 与 +0
	if (a === 0 && b === 0) {
                // -Infinity 与 Infinity
		return 1 / a === 1 / b;
	}
	if (a === b) {
		return true;
	}
       // 处理NaN
	if (numberIsNaN(a) && numberIsNaN(b)) {
		return true;
	}
	return false;
};

通过一段事例来了解Object.is与“===”区别。

> -0 === 0
true
> -0 === +0
true
> 0 === +0
true

> Object.is(-0, 0)
false
> Object.is(-0, +0)
false
> Object.is(0, +0)
true


> NaN === NaN
false
> Object.is(NaN, NaN)
true

好了,今天就到这结束了,下期见。

ps:如果你对node也有兴趣,欢迎关注我公众号:xyz编程日记。