下面代码中 a 在什么情况下会打印 1?
var a =? ;
if (a == 1 && a == 2 && a == 3) {
console.log (1);
}
toString
var a = {
i: 1,
toString () {return a. i++;}
}
==操作符中,如果一个操作数是对象,另一个不是,则调用对象的valueOf()方法取得其原始值再比较,如果返回的还是对象,再接着调用toString()
join、shift
var a = [1,2,3];
a. join = a. shift;
因为是数组对象,对于数组对象,toString()方法返回一个字符串,该字符串由数组中的每个元素的 toString()方法返回值,再经过调用 join()方法连接(由逗号隔开)组成。 数组 toString 方法会调用本身的 join()方法,这里把自己的 join() 方法改写为shift()方法,删除数组的第一项并返回它。
Object.defineProperty
Object.defineProperty(window, 'a', {
get: function () {
return this.value = this.value? (this.value += 1):1;
}
});
//或
var a = 0;
Object.defineProperty(window,'a',{
get:function(){
return ++a;
}
Object.defineProperty接受三个参数
1.属性所在的对象
2.属性的名字
3.一个描述符对象
描述符对象可以是:
1.configurable:表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性,默认值为true。
2.enumerable:表示能否通过for in循环访问属性,默认值为true。
3.writable:表示能否修改属性的值。默认值为true。
4.value:包含这个属性的数据值。默认值为undefined。
比如:
Object.defineProperty(p1,"name",{
configurable : false,
})
console.log(p1); //{ name: 'lisi' }
delete p1.name;
console.log(p1); //{ name: 'lisi' }
//通过设置configurable这个属性为false,delete就不能把name属性给删除掉了。
第三个参数除了可以是数据属性,也可以是访问器属性。
1.get:在读取属性时调用的函数,默认值是undefined
2.set:在写入属性的时候调用的函数,默认值是undefined
比如:
var book = {
year_ : 2004,
edition : 1
}
Object.defineProperty(book,"year",{
get: function(){
return this.year_
},
set: function(newYear){
if(newYear > 2004){
this.year_ = newYear;
this.edition += newYear - 2004
}}})
book.year = 2005;
console.log(book.edition); // 2
console.log(book.year_); //2005
Object.create
var a = Object.create({
count: 0,
valueOf: function () {return ++this. count;}
});
Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__(- proto:新创建对象的原型对象。)。
Symbol.toPrimitive
let a = {
[Symbol.toPrimitive]:((i)=>++i)(0);
}
ES6 引入了一种新的原始数据类型 Symbol,表示独一无二的值。我们之前再定义类的内部私有属性时,习惯使用___xxx,这种命名方式避免别人定义相同的属性名覆盖原来的属性,有了Symbol之后,我们完全可以用 Symbol 值来代替这种方法,而且完全不用担心被覆盖。
除了定义自己使用的 Symbol 值以外,ES6 还提供了 11 个内置的 Symbol 值,指向语言内部使用的方法。Symbol.toPrimitive 就是其中一个,它指向一个方法,表示该对象被转换为原始类型的值时,会调用这个方法,返回该对象对应的原始类型的值,这里就是改变这个属性,把他的值改为一个 闭包 返回的函数。