1.Symbol变量类型
如下代码段,this[species]功能上等同于this.species,但是后者属性类型是字符串,所以需要用点号访问,前者的属性类型是
Symbol类型,作用就是每个从Symbol()
返回的Symbol值都是唯一的,比如var a=Symbol(); var b=Symbol();a==b结果是false
而Symbol('123')这个123就相当于description。
var items=Symbol('items');
var species = Symbol('species'); //声明全局的Symbol变量
class Cat {
constructor() {
this[species] = "cat family"; //猫属于猫科
this.species = "dog family";
this[items]=[1,2,3];
}
}
var myCat = new Cat();
console.log(myCat.species);
console.log(myCat[items][2]);
try {
console.log(myCat[species]);
//不是靠getOwnPropertySymbols方法才能访问Symbol类型的属性吗,
//我哪里理解错了,怎么直接访问了
}
catch (e) {
console.log('get species in [] error')
}
//利用getOwnPropertySymbols访问属性
var objectSymbols = Object.getOwnPropertySymbols(myCat);
console.log(objectSymbols);
//输出结果[Symbol(species), Symbol(items)]
console.log(myCat[objectSymbols[1]][1]);
console.log(myCat[objectSymbols[0]]);
//输出结果3和cat family
2.WeakMap
WeakMap()产生的对象是一个字典,这种方式的核心就是把类的this作为字典的键,在类内和类外this指向不同,导致在类外用this作为键得到值不是我们想要的值。
var items=new WeakMap();//初始化一个字典对象
class Cat{
constructor(){
items.set(this,[1,2,3])
}
print(){
console.log(items.get(this)[1]);//最后输出2
}
}
var oneCat=new Cat();
oneCat.print();
那么能不能骚操作一把
var items=new WeakMap();//初始化一个字典对象
class Cat{
constructor(){
items.set(this,[1,2,3])
}
//新增一个函数,返回指针
get(){
return this;
}
print(){
console.log(items.get(this)[1]);//最后输出2
}
}
var oneCat=new Cat();
var oneCatAdd=oneCat.get();
console.log(items.get(oneCatAdd)[2]);//应该输出3
这说明字典也不稳啊。
我能在对象外部访问属性,核心在于我能访问items,那么只要items是局部变量,我在作用域外就不能访问它。那么怎么把items变成局部变量呢。在类的constructor里面不能声明,否则变成属性;在方法里可以声明,但是不能给别的方法使用,每一个方法里的局部变量对其它方法来说都是透明的。
我们要有一个局部变量,又不能在类里面声明,函数(方法)里面声明的才是局部变量。那么 有一种思路,就是把类的定义还有局部变量的声明都放到函数里。如下
var Catf = (function() {
var items = new WeakMap();
class Cat {
constructor() {
items.set(this, [1, 2, 3])
}
print() {
console.log(items.get(this)[2]); //输出3
}
}
return Cat; //函数返回值是类
})
MyCat=Catf();
var oneCat=new MyCat();
oneCat.print();
更多关于闭包的知识点击下列链接
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures