well-known Symbol ES6 暴露内部操作

由来

ES5的一个中心主旨是将JavaScript中的一些“神奇”的部分暴露出来,并详尽定义了这些开发者们在当时模拟不了的功能。ES6延续了这个传统,新标准中主要通过在原型链上定义与Symbol相关的属性来暴露更多的语言内部逻辑。 MDN 关于well-known Symbol描述

Symbol.hasInstance

执行instanceof时运行的内部方法。 每个函数都有一个Symbol.hasInstance 方法,用于确定对象是否为函数实例。该方法被定义在Function.prototype中,所有对象都继承了instanceof属性的默认行为,且这个方法不可写、不可配置和枚举。

obj instanceof Array;
// 等同于
Array[Symbol.hasInstance](obj);

怎么改写一个不可写的属性呢?这个要使用Object.defineProperty()这个方法了。可以通过以下方法进行改写instanceof 方法实现。

function SObject() {}
Object.defineProperty(SObject, Symbol.hasInstance, {
    value: function(v) {
        return false;
    }
});

let obj = new SObject();
console.log(obj instanceof SObject); //false

Symbol.isConcatSpreadable

对于数组对象,默认情况下,用于concat时,会按数组元素展开然后进行连接(数组元素作为新数组的元素)。重置Symbol.isConcatSpreadable可以改变默认行为。 对于类似数组的对象,用于concat时,该对象整体作为新数组的元素,重置Symbol.isConcatSpreadable可改变默认行为。

let collection = {
    0: "Hello",
    1: "world",
    length: 2,
    [Symbol.isConcatSpreadable]: true
}

let messages = [ "Hi"].concat(collection);
console.log(messages.length); // 3
console.log(messages); // (3) ["Hi", "Hello", "world"]

var alpha = ['a', 'b', 'c'], 
    numeric = [1, 2, 3]; 

numeric[Symbol.isConcatSpreadable] = false;
var alphaNumeric = alpha.concat(numeric); 

console.log(alphaNumeric); // 结果: ['a', 'b', 'c', [1, 2, 3] ]

是不是很神奇?我们现在可以编辑影响一些内部函数了! 还有更多内部暴露的方法。

与string相关的Symbol.match、Symbol.replace、Symbol.search和Symbol.split

Symbol.toPrimitive 类型转换

Symbol.toStringTag

更多属性参考MDN

原文链接:segmentfault.com

上一篇:well-known symbol es6 暴露内部操作
下一篇:ArcGis for JavaScript SDK

相关推荐

  • 领略原生 javascript es6~es10 的魅力

    图片描述(https://img.javascriptcn.com/f3663fe101c5d4062fda74e1ae5e25d6 "图片描述") 作为前端开发工程师,盲目追逐框架似乎有点舍本逐末...

    8 个月前
  • 领略原生 JavaScript ES6~ES10 的魅力

    图片描述(https://img.javascriptcn.com/98bc3ace8fade84c91d94f42b7cc5301 "图片描述") 作为前端开发工程师,盲目追逐框架似乎有点舍本逐末...

    8 个月前
  • 面试题:没有es6老项目,如何用jq解决异步的问题?

    我们都知道es6提供了promise异步写法,但是大部分的公司都是jq写的,那我们如何用Jq来写和promise异步一样的写法呢?这个知道的人不多下面我们就来写写把 注意: 1 JQ 1.5以上 ...

    2 年前
  • 面试题3:ES5、ES6两种方式实现继承

    写一个类Person,拥有属性age和name,拥有方法say(something)再写一个类Superman,继承Person,拥有自己的属性power,拥有自己的方法fly(height) ...

    25 天前
  • 面试深入一、ES6模块化、安装和打包

    开发环境已经普及使用 浏览器环境却支持不好(需要开发环境编译) 内容很多,重点了解常用语法 面试:开发环境的使用 重点语法的掌握 问题 模块化如何使用...

    2 年前
  • 阮一峰ES6全面回顾

    9月抽空重新回顾了下ES6所有知识点,整个回顾过程既惊喜又感慨,感慨开发这么久好像真的没有好好的静下心去读一本好的书,大多情况下只是在使用的时候用到了,不熟悉或者感兴趣再去走马观花一通,感慨之余也发...

    7 个月前
  • 通过选择进口ES6模块

    通过选择进口ES6模块...

    2 年前
  • 通过 20 个棘手的ES6面试问题来提高咱们的 JS 技能

    作者:Alex 译者:前端小智 来源:dev.to 今天最后一天了,上个月自己花了 1300 买了阿(a)里(li)的 服 务 器来学习 node 及对应的框架,在 号之前它们有做活...

    7 个月前
  • 通俗易懂理解ES6 - 变量的解构赋值

    引言 万丈高楼平地起,欲练此功,必先打好基本功: ) 编程语言总少不了变量赋值;ES6中引入了新的赋值形式:解构赋值;解构赋值大大的简化了变量赋值的代码,解构赋值仅能对具有迭代器(Iterator...

    9 个月前
  • 进口使用ES6语法和动态路径[复制]模块

    Félix Sanz(https://stackoverflow.com/users/3181234/f%c3%a9lixsanz)提出了一个问题:Importing modules using ES...

    2 年前

官方社区

扫码加入 JavaScript 社区