01 | delete 0:JavaScript中到底有什么是可以销毁的
01 | delete 0:JavaScript中到底有什么是可以销毁的
讲述:周爱民
时长18:11大小16.65M
习惯中的“引用”
到底在删除什么?
表达式的结果是什么?
规范中的“引用”
还会发生什么
告诉我这些有什么用
知识回顾
思考题
赞 30
提建议
精选留言(95)
- 海绵薇薇2019-11-19老师好,我又来了:-) 1. delete 0 这里的0是一个值(就当前情况),而不是引用是吗? 2. delete x (x不存在) 返回true x 表达式返回的应该是一个引用,并且环境中并没有表示这个引用不能被删除,这个理解对吗? 但是文章中有提到delete只能删除属性这一种引用,糊涂了,估计这里的理解还是有问题。 3. delete null 返回true delete undefined 返回false 为啥啊?不都是值吗? 4. 还想知道昨天提问的1和2两条是不是漏洞百出啊,就想知道个结果😁。展开
作者回复: Oh~ 哈哈,你是说昨天有一个问题我只回复了3,没有回复1和2两条吗?那两条,是全对的,所以……嗯嗯,我只是没有回复确认而已。你对ECMAScript中的“引用规范类型”的使用场景和过程推演都是正确的。 关于今天的前3个问题,1是正确的。 2你也是对的。但是有一点,这个x的确会得到一个引用,称为(UnresolvableReference)。而这一段逻辑在ECMAScript里面写的是“if IsUnresolvableReference, then return true”。也就是说,ECMAScript约定对于这种情况就是这么返回的,这属于规范约定(并且如果在这时发现是严格模式,就抛异常了)。关于这里,你可以看一看: https://tc39.es/ecma262/#sec-delete-operator-runtime-semantics-evaluation 不过问题3,你倒是提到了一个“少有人知”问题,哈哈,这个问题我是漏讲了,而且其实还挺有趣、挺关键的。 是这样,早期的JavaScript中,undefined是一个特殊值,是在运行期中通过void运算,或者不返回值的函数,又或者一个声明了但未赋值的变量,等等类似这样的情况来“计算得到”的。所以在JavaScript的早期版本中,你没有办法直接判断“undefined是undefined”,例如无法写出“x === undefined”这样的代码,而你只能写类似“typeof(x) ==='undefined'”这样的代码。 后来(其实也没有太久),规范就约定把undefined作为可以缺省访问的名字,类似于null。但是这个时候就带来了一个矛盾,因为这个undefined很重要,早期的绝大多数框架或引擎都把它作为一个“全局名字”给声明了。也就是说,ECMAScript现在既没有办法将它规范成一个keyword,也没有办法处理成保留字等等,它看起来像null,但又没有办法在规范层面强制它。所以……ECMAScript就搞了一个“奇招”: > 我们把undefined声明成全局的属性,怎么样?! 嗯嗯,很好。所以你看,现在的引擎上面undefined看起来长得跟null值差不多,而且在ECMAScript规范中它们都还是平级的(是原始值),而且它们的作用也很接近,最后他们都还是从最初的JavaScript 1.x中就存在的概念,但是undefined/null两者却在实现上完全不同:undefined是一个全局属性,而null是一个关键字。 由于undefined是全局属性,所以`delete undefined`其实就是`delete global.undefined`,是删除引用,而不是删除值。而这个属性是只读的,所以就返回false了。 例如你可以试试下面的代码: > Object.getOwnPropertyDescriptor(global, 'undefined') { value: undefined, writable: false, enumerable: false, configurable: false }
共 11 条评论100 - 海绵薇薇2019-11-22hello 老师好,感谢老师之前的回答:) 突然想到,访问不存在的变量x报ReferenceError错误,其实是对x表达式的的Result引用做getValue的时候报的错误,然后为啥typeof x和delete x不报错,因为这两个操作没有求值。
作者回复: 强烈点赞!你这个就属于一通百通的例子。弄明白了Result用来做引用和值的方法/原理,一些具体现象就迎刃而解了! ^^.
共 9 条评论63 - 潇潇雨歇2019-11-111、如果x根本不存在,delete x什么也不做,返回true 2、如果x只读,delete object.x不能删除掉x属性,返回false;如果在严格模式下,会报错:TypeError: Cannot delete property 'c'
作者回复: 赞的!+1 其实第1个问题的潜在问题是:这种情况下,x是什么呢?它显然是语法可以识别的东西,但如果这样,在语法上它是什么,且在执行环境中它又是什么? 而第二个问题的答案,其实也会回到第一个问题上。如果是在严格模式上,第一个问题的答案是什么?并且,为什么它们不同? 所以,呵呵,其实细一点的看,这两个问题还可以挖更多的呢。^^.
共 4 条评论30 - 潇潇雨歇2019-11-11关于delete的知识,大家可以看下MDN的讲解:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/delete 以及这篇深入delete博客:http://perfectionkills.com/understanding-delete/
作者回复: 谢谢 @潇潇雨歇
共 7 条评论25 - SOneDiGo2019-11-22想问下老师如何理解用delete处理array element实际上在底层是如何操作的? 例如:array = [1,2,'1'] 为什么 delete array[2] 后数组就成了[1,2,undefined/empty]?
作者回复: 对于array来说,你理解为一个普通对象就可以了,只是一些array原型上的方法能帮助你处理array.length这个属性而已。 有多少个有效的element,那么就有多少个同名的(数字下标的)属性;而array.length记录着这个最大值。除了这一点,没有任何与其它对象不同。 所以你用array.pop()或array.push()等操作,甚至直接使用array[i]都可以影响到array.length这个属性——因为这些操作内部都会处理它。但是,你用delete去根本不会处理这个属性——因为delete是把array[i]当一个一般属性处理的,根本不知道array.length的存在。 例如: ``` > x = new Array(8) > x.length 8 > x[x.length] = 8 // add to last > x.length 9 > x.push(10) // push 10 > x.pop() // pop > x.length 9 > delete x[8] true > x.length 9 ``` 至于删除delete array[2],则array[2]位置上是undefined,这个与delete操作无关。而是因为你“读取一个不存在的属性,它的值就是undefined”。
19 - 海绵薇薇2019-11-18感谢老师指点😁 ref:语法上的引用 我又看了几遍文章并根据提供的连接,得出如下结论: 1. var x x = 0 console.log(x) x 表达式返回的是一个ref({referencedName: 'x', base: Environment Record}),然后计算值getValue(ref)得到具体的值,具体的值会分为传统意义上的基本类型和引用类型 2. 衍生出下面的猜想 var obj obj = {a: 1} console.log(obj.a) obj.a 也是一个ref({referencedName: 'a', base: obj}),然后计算值的时候getValue(ref)得到具体的值1 3. 关于表达式的结果Result的疑问。 文中说:表达式的值,在 ECMAScript 的规范中,称为“引用”。(表达式的结果(Result)是引用。) 但是后文说Result可能是引用/值。 这里的值我不能很好的理解。值指的是另一种引用的格式吗?例如链接文档中提到的base其实有很多种值 undefined, Object, a Boolean, a String, a Symbol, a Number。值指的是{base: 0}这种引用吗?如果不是这样的话base的Boolean等基本值类型有啥用啊? 还是说 0 这个表达式的Result就是0这个值? 期待老师的指点😁展开
作者回复: 关于3,我一般是用Result来表达它是表达式执行结果的“未决状态”。就是执行出结果来了,但没确定是作为lrs还是rhs,所以这种情况下,它就是未决的。 当你确定了一个Result用作lrs,那么它就是引用;如果确定它用作rhs,那么它就是值(将由引擎隐式地调用`GetValue()`)。
共 3 条评论19 - 潇潇雨歇2019-11-16看的第三遍。还是要去看看规范加深理解。 如果x根本不存在,delete x操作时,x首先是一个表达式,语义上是一个引用,然后去寻找该引用的result,但是x根本不存在,是找不到的。也就做不了什么,返回ture。 如果obj.x是只读的或者不可配置的,表示他是不能删除的,但是他是实实在在的引用,是可以求值得到Result的,所以返回false。表示不能删除。
作者回复: :) +1
共 2 条评论18 - Ming2019-11-11乍一读,云里雾里。翻了文档并做测试,总结如下: delete 操作符用于删除对象的属性,它接收一个表达式,该表达式应返回对象属性的引用。 1. 如果表达式返回的结果是引用: 当该引用是 let 或 const 定义的,delete 执行结果总是 false; 当引用作为对象的属性不存在时,delete 对象的属性,执行结果为 true,表示未处理; 当该引用为 window 对象的属性且是 var 定义的,delete window 对象的属性,执行结果为 false,表示处理失败(获取属性描述符时为不可配置); 如果在全局环境下显示定义一个属性描述符为可配置的全局属性,执行 delete,结果是 true,表示操作成功; 当该引用为非 window 对象的属性且是 var 定义的,delete 非 window 对象的属性,执行结果为 true,表示处理成功(获取属性描述符时为可配置)。 2. 如果表达式返回的结果是值,如数字、字符串等,delete 执行结果为 true,表示未处理。展开
作者回复: 其实这一讲的核心是关于“引用/值”在ECMAScript规范类型中的使用与理解,而不是(不仅仅是)delete的使用。所以呢,解释delete这个操作的种种现象,最好是在ECMAScript规范所讨论的语言模型中来叙述,这样更容易讲得清楚。 比如说,`x`如果是一个属性(包括是global的属性),那么`delete x`的是否成功就取决于属性描述符,以及属性存取的过程(是否在严格模式中等等)。这样就Ok了,而不需要细致地列举每一种情况。
共 4 条评论16 - Wiggle Wiggle2019-11-12即便 obj.x 是一个 function,当 obj.x 作为右手端时,也会被 GetValue 方法抽取出值来,而这个“值”并不是直觉上的数字或字符串。这里是有恍然大悟的感觉的,“值”和“引用”应当从严格的规范定义层面理解,而不能从直觉上来理解,只要满足定义,那就是“值”/“引用”。
作者回复: 赞的!就是这样!
15 - 隔夜果酱2019-11-11既然delete这么鸡肋,只能删除对象的成员. 那么后来的版本中为什么不进行改进呢? 比如限定其只能用delete obj.x这种语法格式. 或者加入trycatch,对删除value的操作直接报错呢?
作者回复: 这个问题就牵扯得大了。 最早javascript中是没有明确、显式的global这个对象的,在宿主环境(例如浏览器中)你可以用window.x去访问它,这算是宿主在实现引擎的时候的约定。但是,仅只从引擎的角度上来说,既没有window,也没有global,更没有Global。所以,全局的变量虽然是作为全局属性名存在着,却没有办法写成global.x这样的引用。 而global这个全局名字,直到现在在ECMAScript中都还是个没被规范的东西。TC39有一个提案(https://github.com/tc39/proposal-global)专门来定义它,现在到了stage3,应该不会被否决了。但即使如此,这个东东也不叫global,而改名成了globalThis。——原本提案阶段是叫global的,但应用中有问题,所以就改了。 关于globalThis这个说法,又得是一段历史了。因为早期的JavaScript约定普通函数在“不作为对象方法调用”的时候,this值默认指向这个全局的global。所以,这也就是著名的代码“global = (new Function('return this')()”,或“global = Function('return this')()”的由来。 ^^.
14 - 余文郁2019-11-11老师,JS是基于对象的语言,不是面象对象的语言吧,感觉第二段这有点不妥,虽然ES6增加了class语法,但只是原型的语法糖而已
作者回复: 在后面我会再着重地讲到JavaScript对面向对象的理解。 如今我们对OOP的理解其实添加了太多应用的色彩。事实上,JavaScript对OOP的理解是很精彩、很学术,以及很完整的。不过这些内容大概要到第11讲之后了。 至于“面向对象”还是“基于对象”,其实JavaScript 1.0是有类而无继承的,而JavaScript 1.1才开始使用原型来实现继承,这个时候它又抛弃了(严格意义上的)类。 当然,上面看起来有点儿绕着你的问题在讲。所以,如果再确切地、准确无误地回复你的问题,那么应该是说:所谓面向对象的三个原则(封装、继承与多态),在严格意义上,后两者是多余的。所以不必过度去强调这些性质之于面向对象的重要性。
共 5 条评论12 - 渭河2019-11-21这句话要怎么理解呀 所谓值类型中的字符串是按照引用来赋值和传递引用(而不是传递值)的
作者回复: 这就是“传统中的‘引用’”用来解释这类现象的时候出现的麻烦。很典型的一个例子,话表达的是正确的,内容是正确的,说法也正确,就是特别特别难于理解。 首先,“值类型中的字符串”是指什么呢?是指typeof(x) === 'string'中的那个`x`。在传统的javaScript概念中,这样的x是值类型,而不是引用类型。 那么值“该怎么赋值和传递”呢?如果x的值是1,那么y = x的话,就是把1这个值“抄写”到y里面去。这是“正常的值”的处理方法,但是如果“字符串值”也这么处理,就完蛋了,因为字符串可能无数多个字符,那么当`y = x`按照“正常的值处理方法”来实现的话,这个“值的复制”的开销就受不了。 所以: 1. “值类型中的字符串”,是指照 2. “引用来赋值和传递引用”的;且, 3. 它是只传递引用(而不是传递值)的。 如上。只是说起来特别麻烦而已。
共 2 条评论11 - 桃翁2020-03-19我突然 明白了 (obj.func=obj.func)()这种方式会丢掉obj里面的this,因为等号右边的obj.func是值,所以得到的仅仅是个函数这个值,而不是引用。 老师我理解得是对的吗?
作者回复: Yes!+5
共 3 条评论10 - ssala2019-11-14关于delete,搜集了一些资料,结合代码测试,我目前是这样理解的:delete为一元操作符,其操作数为一个表达式,如果表达式的求值结果是一个值,那么`delete 值`直接返回true,表示该操作没有异常。如果表达式求值结果是一个引用,那么`delete 引用`则会有如下表现,如果引用是可删除的,则直接删除该引用,返回true,否则返回false。 关于属性/property的可删除特性,参照这篇文章:http://perfectionkills.com/understanding-delete/ 关于引用和值的理解,我用段代码说明,如下: ``` var x = {a: 20} ``` 代码中,x是引用,它"指向"执行系统中{a: 20}的一个对象,而{2: 20}则是值,它对应执行系统中内存上的一块区域。x.a是引用,它"指向"执行系统中内存20这个值,而20是值,它也对应执行系统中内存上的一块区域。因此: ``` delete x // `false` ,x为表达式,求值结果为global.x,且该属性是用var来声明的,其特性是不可删除 delete 20 // `true`,当执行系统遇到20字面量时,认为其为表达式,对其求值以后得到20这个值,delete 值返回true delete x.a // `true` x.a 为引用,且可以删除 ``` 另外关于delete x,若x不存在,我的解释是:x为表达式,由于未定义,表达式求值结果是未定义的,但是虽然未定义,但求值结果仍然是值,而delete 值就返回true。不知这种解释是否正确?展开
作者回复: Yes. 对的。 其实只要理解到`delete {}`中的对象字面量其实是“值”,那么就一通百通了。
共 2 条评论9 - blueBean2020-02-21表达式的值,在 ECMAScript 的规范中称为“引用”。 ECMAScript 约定:任何表达式计算的结果(Result)要么是一个值,要么是一个引用。 上面这两句话矛盾了吧
作者回复: 并不是矛盾,只是这里解释起来比较别扭。因为“Value”和“Result”,以及“值和引用”在上下文中都存在多种含义。 【第一句】 ``` 表达式的值,在 ECMAScript 的规范中称为“引用”。 ``` 这一句讲的时候,上下文中是将表达式与语句放在一起讨论的。原文是“(你)执行的是一个语句,那么……;而如果你使用……表达式执行,那么……”。前者是语句的值,后者表达式的值。——它们都分别是“一个称为结果(Result)的东西”。 这样对比来讲的时候,我向来会解释成: > 语句和表达式都是有值的,语句的值是“完成(规范类型)”,而表达式的值是“引用(规范类型)”。 这个区别在后面的章节里面还会有,而且也还会这么讲。主要是这样讲起来清晰、简单,分别起来也很容易。——但是,这样讲并不“准确”。因为事实上表达式的“结果(Result)”也可以是完成类型,而语句的结果还包括一个所谓的“Empty”值。 在第一章中,要把所有关系到的概念讲清楚是很难的,真要那样讲概念,大概也让人读不下去。所以这里说的是一个简单的区分,也就是如何区别“表达式的值 vs 语句的值”。 【第二句】 ``` ECMAScript 约定:任何表达式计算的结果(Result)要么是一个值,要么是一个引用。 ``` 这一句是完整而正确的。但是如同上面的讨论中所说的,它其实也并不“绝对完整”,因为有一部分表达式事实上是在返回“完成(规范类型)”。只不过当这种情况发生时,后续的计算过程会从“完成(规范类型)”中直接取值,因此在计算过程中感觉不到“非值”的结果(Result),这是一种中间状态。 总之,这些内容在后续的章节中还会介绍。会逐渐更新和补全。第一章,以及前几章的内容,要通贯起来看,有很多地方的写法或者讲法,是不得以而(暂且)为之的。关于这一点,我在“加餐(选学的章节)”里面说过,也就可以先略过去,看不明白,或者看起来矛盾的地方,后面再读到的时候,就了解了。
8 - 仰望星空2019-11-11老师的英语发音delete偏差的有点多
作者回复: 这个这个,惭愧呀惭愧~ 我的口语不是一点半点的糟糕(当然,其实不仅仅只是口语糟糕)。我尽量……注意……后面的课程~ 多谢多谢~ 惭愧呀~ :(~
7 - Marvin2019-11-20关于文中delete x的解释,我有一点疑问。 文中是这样说的: 于是,我们现在可以解释,当 x 是全局对象 global 的属性时,所谓delete x其实只需要返回global.x这个引用就可以了。而当它不是全局对象 global 的属性时,那么就需要从当前环境中找到一个名为x的引用。找到这两种不同的引用的过程,称为 ResolveBinding;而这两种不同的x,称为不同环境下绑定的标识符 / 名字。 如果把x解释为引用,而且先寻找global.x,当不是全局属性再寻找当前环境的话: ``` window.apple = 10; let apple = 10; delete apple; // false ``` 上面的代码应该先去全局寻找apple引用,那么删除就成功了,应该返回true才对,而不是false。展开
作者回复: 哦。确实是这样的。 但是这个问题与delete运算符无关,这个取决于`delete`将`apple`作为一个名字被"发现(resolving)"的过程。 由于全局环境的作用域是由global对象和一个词法环境(共同)构成的,所以它查找上面这个名字的顺序是先词法声明,然后才是global对象上的属性的。这个部分请参见ECMAScript: https://tc39.es/ecma262/#sec-global-environment-records-getbindingvalue-n-s > If DclRec.HasBinding then return DclRec.GetBindingValue(); > else return ObjRec.GetBindingValue()
6 - Mr_Liu2019-11-12思考题1:delete x x不存在返回的是true 2: 删除会返回false,严格模式会报错 第一遍听感觉有些云里雾里的感觉,又听了一遍加实践。但是有一点不理解或者不知道理解的对不对,希望老师解答一下 问题一: 例如var a = '123' delete a 返回的是false , 再次输入a 得到结果依然是 ‘123’, 这是说明delete 没有起作用,其没有起作用的原因是因为 var a = '123' 中的a 是基本数据类型,不是引用类型,所以删除a 元素失败,借此印证了所讲的delete 删除的是表达式或者引用类型的结果。印证这句话的另一个例子是: var obj = { a: '123' }, var b = obj.a delete b 返回false , 因为b = obj.a 属于一个赋值语句,b 也是个基本数据类型,所以也不起作用 那么修改成 var obj = { a: '123', b: { name: '123' } } var val = obj.b deletet val 返回的依然是false 后来会读了一下,有这样一句话:delete 其实只能删除一种引用,即对象的成员(Property) 那么 delete x 还有什么存在的意义么。 问题二: 接着我使用delete obj.a 返回的是true ,再次输入 obj.a 返回的就是undefined 但如果我使用 var val = obj.b delete obj.b 返回的是true 然后打印 obj.b 为undefined; val 为 {name: '123'} ,那老师的那句delete实际上是删除一个表达式的、引用类型的结果(Result),而不是在删除 x 表达式,或者这个删除表达式的值(Value)。是否可以理解为实际是是删除一直引用呢。展开
作者回复: 问题1中,你的思考方向错了。`delete a`不起作用的原因是`var`声明导致的,而不是因为`a 是基本数据类型`。举例来说, `with (x = {a: 100}) delete a;` 这个例子的结果中x.a是不存在的,但`a 也是基本数据类型`呀。所以是无关的。 “delete x 还有什么存在的意义么”这个问题我之前回复过另一个留言,你找找。 关于问题二,关键在于你所理解的“引用与值”,跟JavaScript内部所理解的“引用与值”是不一样的。也正是因此,我在这一讲的一开始用大量文字讨论了二者的区别。简单地来说,如果有表达式`x = x`,那么同一个变量`x`,在上述表达式中,左侧的这个是它的引用,左侧的是它的值。如果放在代码中看: x = 5; // 在JavaScript语言中,'5'是“值类型” x = x; // 在ECMAScript规范中,左侧是“引用x”,右侧是“值x”。 我一直用“结果(Result)”来强调表达式“表达式计算的结果”,就是因为对于`x = x`来说,左侧和右侧都是表达式,左侧的结果是“lhs/引用(reference)”,而右侧的结果是“rhs/值(value)”。 所以所谓“结果(Result)”,在不明确它的手性或用处之前,是二个意思都包含的。
共 2 条评论6 - James2020-02-17老师问你一个问题。 var a = 1 delete(a) // false 这个为什么返回false啊,我查看不是只读的。 Obect.getOwnPropertyDescriptor(window, 'a') { value: 1 writable: true enumerable: true configurable: false }展开
作者回复: 没说它是只读的呀。 configurable: false,说明它是不可变更配置的,亦即是不能删除该属性,也不能修改属性描述符。
5 - 老姚2020-01-04下面从5.1语言规范上找到的,希望能辅助大家理解。内容copy于某个版本的翻译。 一、类型分类 类型分为 ECMAScript 语言类型 与 规范类型 。 ECMAScript 语言类型 是 ECMAScript 程序员使用 ECMAScript 语言直接操作的值对应的类型。ECMAScript 语言类型包括 未定义 (Undefined)、 空值 (Null)、 布尔值(Boolean)、 字符串 (String)、 数值 (Number)、 对象 (Object)。 规范类型 是描述 ECMAScript 语言构造与 ECMAScript 语言类型语意的算法所用的元值对应的类型。规范类型包括 引用 、 列表 、 完结 、 属性描述式 、 属性标示 、 词法环境(Lexical Environment)、 环境纪录(Environment Record)。规范类型的值是不一定对应 ECMAScript 实现里任何实体的虚拟对象。规范类型可用来描述 ECMAScript 表式运算的中途结果,但是这些值不能存成对象的变量或是 ECMAScript 语言变量的值。 在本规范中,我们将「x 的类型」简写为 Type(x) ,而类型指的就是上述的 ECMAScript 语言类型 与 规范类型 。 二、规范类型中的引用类型定义 引用类型用来说明 delete,typeof,赋值运算符这些运算符的行为。例如,在赋值运算中左边的操作数期望产生一个引用。通过赋值运算符左侧运算子的语法案例分析可以但不能完全解释赋值行为,还有个难点:函数调用允许返回引用。承认这种可能性纯粹是为了宿主对象。本规范没有定义返回引用的内置 ECMAScript 函数,并且也不提供返回引用的用户定义函数。(另一个不使用语法案列分析的原因是,那样将会影响规范的很多地方,冗长并且别扭。) 一个 引用 (Reference) 是个已解决的命名绑定。一个引用由三部分组成, 基 (base) 值, 引用名称(referenced name) 和布尔值 严格引用 (strict reference) 标志。基值是 undefined, 一个 Object, 一个 Boolean, 一个 String, 一个 Number, 一个 environment record 中的任意一个。基值是 undefined 表示此引用可以不解决一个绑定。引用名称是一个字符串。 本规范中使用以下抽象操作接近引用的组件: GetBase(V)。 返回引用值 V 的基值组件。 GetReferencedName(V)。 返回引用值 V 的引用名称组件。 IsStrictReference(V)。 返回引用值 V 的严格引用组件。 HasPrimitiveBase(V)。 如果基值是 Boolean, String, Number,那么返回 true。 IsPropertyReference(V)。 如果基值是个对象或 HasPrimitiveBase(V) 是 true,那么返回 true;否则返回 false。 IsUnresolvableReference(V)。 如果基值是 undefined 那么返回 true,否则返回 false。 三、delete运算符 产生式 UnaryExpression : delete UnaryExpression 按照下面的过程执行 : 1.令 ref 为解释执行 UnaryExpression 的结果。 2.如果 Type(ref) 不是 Reference,返回 true。 3.若 IsUnresolvableReference(ref) 则 , 如果 IsStrictReference(ref) 为 true ,抛出一个 SyntaxError 异常。 否则,返回 true。 4.如果 IsPropertyReference(ref) 为 true 则: 返回以 GetReferencedName(ref) 和 IsStrictReference(ref) 做为参数调用 ToObject(GetBase(ref)) 的 [[Delete]] 内置方法的结果。 5.否则 , ref 是到环境记录项绑定的 Reference,所以: 如果 IsStrictReference(ref) 为 true ,抛出一个 SyntaxError 异常 . 令 bindings 为 GetBase(ref). 返回以 GetReferencedName(ref) 为参数调用绑定的 DeleteBinding 具体方法的结果。展开
作者回复: 谢谢。赞的! 关于ES6之前的ECMAScript翻译,大概最精良的算是w3c的那一份,这在加餐的下节(https://time.geekbang.org/column/article/175261)里专门说了一下。这门课程有意地避开了ECMAScript的一些讲述方法(当然也有一些地方是特意去讲ECMAScript的),主要是考虑到课程自己的整体体系和讲述的逻辑,还是与ECMAScript有些差异的。而且,讲ECMAScript的话……讲不完啊。哈哈哈~ 多谢。
5