一、Symbol
以下内容都是学习软一峰的es6的笔记,详情请参考http://es6.ruanyifeng.com/
1.ES6 引入了一种新的原始数据类型Symbol
,表示独一无二的值,可以保证不会与其他属性名产生冲突。
使用一:
let s = Symbol(); typeof s // "symbol"
使用二:参数只是用来描述
var s1 = Symbol('foo'); var s2 = Symbol('bar'); s1 // Symbol(foo) s2 // Symbol(bar) s1.toString() // "Symbol(foo)" s2.toString() // "Symbol(bar)"
2.Symbol 值不能与其他类型的值进行运算,会报错。
3.Symbol 值可以显式转为字符串和布尔值,但是不能转换为数值
4.由于symbol的特性,所以可以将其用在对象属性上,这样可以避免某个属性被覆盖或者改写。
var mySymbol = Symbol(); // 第一种写法 var a = {}; a[mySymbol] = 'Hello!'; // 第二种写法 var a = { [mySymbol]: 'Hello!' }; // 第三种写法 var a = {}; Object.defineProperty(a, mySymbol, { value: 'Hello!' }); // 以上写法都得到同样结果 a[mySymbol] // "Hello!"
5.Symbol 值作为对象属性名时,不能用点运算符。
var mySymbol = Symbol(); var a = {}; a.mySymbol = 'Hello!'; a[mySymbol] // undefined a['mySymbol'] // "Hello!"
6.在对象的内部,使用 Symbol 值定义属性时,Symbol 值必须放在方括号之中。
let s = Symbol(); let obj = { [s]: function (arg) { ... } }; obj[s](123);
let obj = {
[s](arg) { ... }
};
7.Symbol 值作为属性名时,该属性还是公开属性,不是私有属性。
8.作用:
定义一组常量,保证常量组里面的值是不相等的
log.levels = { DEBUG: Symbol('debug'), INFO: Symbol('info'), WARN: Symbol('warn') }; log(log.levels.DEBUG, 'debug message'); log(log.levels.INFO, 'info message');
保证逻辑正确执行
const COLOR_RED = Symbol(); const COLOR_GREEN = Symbol(); function getComplement(color) { switch (color) { case COLOR_RED: return COLOR_GREEN; case COLOR_GREEN: return COLOR_RED; default: throw new Error('Undefined color'); } }
二、js的继承
以下内容是这篇文章里面内容的复制品,只是为了以后自己方便查看:http://www.cnblogs.com/ayqy/p/4471638.html
1.基本概念
/*
* 约定
*/
function Fun(){
// 私有属性
var val = 1; // 私有基本属性
var arr = [1]; // 私有引用属性
function fun(){} // 私有函数(引用属性)
// 实例属性
this.val = 1; // 实例基本属性
this.arr = [1]; // 实例引用属性
this.fun = function(){}; // 实例函数(引用属性)
}
// 原型属性
Fun.prototype.val = 1; // 原型基本属性
Fun.prototype.arr = [1]; // 原型引用属性
Fun.prototype.fun = function(){}; // 原型函数(引用属性)
2.原型链继承
function Super(){
this.val = 1;
this.arr = [1];
}
function Sub(){
// ...
}
Sub.prototype = new Super(); // 核心
var sub1 = new Sub();
var sub2 = new Sub();
sub1.val = 2;
sub1.arr.push(2);
alert(sub1.val); // 2
alert(sub2.val); // 1
alert(sub1.arr); // 1, 2
alert(sub2.arr); // 1, 2
优点:
- 简单,易于实现
缺点:
-
修改sub1.arr后sub2.arr也变了,因为来自原型对象的引用属性是所有实例共享的。
可以这样理解:执行sub1.arr.push(2);先对sub1进行属性查找,找遍了实例属性(在本例中没有实例属性),没找到,就开始顺着原型链向上找,拿到了sub1的原型对象,一搜身,发现有arr属性。于是给arr末尾插入了2,所以sub2.arr也变了
-
创建子类实例时,无法向父类构造函数传参
3.构造函数
function Super(val){
this.val = val;
this.arr = [1];
this.fun = function(){
// ...
}
}
function Sub(val){
Super.call(this, val); // 核心
// ...
}
var sub1 = new Sub(1);
var sub2 = new Sub(2);
sub1.arr.push(2);
alert(sub1.val); // 1
alert(sub2.val); // 2
alert(sub1.arr); // 1, 2
alert(sub2.arr); // 1
alert(sub1.fun === sub2.fun); // false
优点:
-
解决了子类实例共享父类引用属性的问题
-
创建子类实例时,可以向父类构造函数传参
缺点:
- 无法实现函数复用,每个子类实例都持有一个新的fun函数,太多了就会影响性能,内存爆炸。。
4.组合
function Super(){
// 只在此处声明基本属性和引用属性
this.val = 1;
this.arr = [1];
}
// 在此处声明函数
Super.prototype.fun1 = function(){};
Super.prototype.fun2 = function(){};
//Super.prototype.fun3...
function Sub(){
Super.call(this); // 核心
// ...
}
Sub.prototype = new Super(); // 核心
var sub1 = new Sub(1);
var sub2 = new Sub(2);
alert(sub1.fun === sub2.fun); // true
优点:
- 不存在引用属性共享问题
- 可传参
- 函数可复用
缺点:
- (一点小瑕疵)子类原型上有一份多余的父类实例属性,因为父类构造函数被调用了两次,生成了两份,而子类实例上的那一份屏蔽了子类原型上的。。。又是内存浪费,比刚才情况好点,不过确实是瑕疵
三、react进阶好文
https://segmentfault.com/a/1190000005990091
http://www.ruanyifeng.com/blog/2016/06/css_modules.html css modules的使用,可以结合less等
https://segmentfault.com/a/1190000008356407
https://segmentfault.com/a/1190000008925295#articleHeader4 react性能优化