十五的学习日记20160927-ES6学习/中间变量/数组坑/

十五的学习日记20160927


JavaScript

  1. ES6新特性之对象简写(属性简写,特性方法简写,可计算属性值),注:多个同名属性会被后者覆盖
// Shorthand property names (ES6)
var a = "foo", b = 42, c = {};
var o = { a, b, c };

// Shorthand method names (ES6)
var o = {
  property([parameters]) {},
  get property() {},
  set property(value) {},
  * generator() {}
};

// Computed property names (ES6)
var prop = "foo";
var o = {
  [prop]: "hey",
  ["b" + "ar"]: "there",
};
  1. [[property]]的用法,[[property]]又称作特性,或者属性描述用于给属性添加额外的能力.在一些语境中, attribute是对外的属性,而property则是对内的属性,这有点像特点和天赋的区别,特点是展示给别人看的,而天赋却是特点的根本.
    ES6中,setter的用法 :set + 属性名+参数+函数体
    举例说明:
var o = {
  set current (str) {//给current属性设置了一个setter方法,和普通方法不同的是, 直接访问setter不会返回函数体.
    this.log[this.log.length] = str;
  },
  log: []
}
o.current="1234"    //"1234"
o.log				//["1234"]
o.current			//undefined

下面来看ES5的写法:必须使用Object.definePropertyObject.defineProperties来定义[[property]],

var o={};Object.defineProperty(o,"b",{get:function(){return this}});
o.b;//返回b{};  
  1. 一道题,考察js的引用数据类型
function foo(x) {x.push( 4 );x = [4,5,6];x.push( 7 ); return window.a}
var a = [1,2,3];
foo( a );//[1,2,3,4]
//结果是显然的,那么怎样修改a本身?
function foo(x) {x.push( 4 );x.length = 0; x.push( 4, 5, 6, 7 ); return window.a}
var a = [1,2,3];
foo( a );//[4,5,6,7]
//对引用类型进行值传递,需要一份深拷贝
foo(a.slice());
  1. 中间变量的意义:
    比如字符串.length的运作过程是将字符串包装成包装类,然后获取length属性,所以在for循环中每次都要执行这样的操作一次,这很吃性能,最好是把他储存为中间变量.
  2. 包装类的解除包装可以通过访问valueOf属性获得基本值.
  3. 数组的一些坑:
var a=new Array(3);//[undefined × 3]
var b=[,,,]//三个逗号居然返回[undefined × 3]
var c=[undefined,undefined,undefined]
var d=[];d.length=3;//[undefined × 3]
b.map((i,x)=>{return x;})//[undefined × 3],因为下标不真实存在!
c.map((i,x)=>{return x;})//[0,1,2]!! 因为下标真实存在!
//如果你想创建空数组,最好的办法是
Array.apply(null,{length:3})//返回[undefined,undefined,undefined]

7.日期类型两种获得当前日期的方法

Date.now() equal (new Date()).getTime()
  1. symbol用法:Symbol.for()Symbol()这两种写法,都会生成新的Symbol。它们的区别是,前者会被登记在全局环境中供搜索,后者不会。Symbol.for()不会每次调用就返回一个新的Symbol类型的值,而是会先检查给定的key是否已经存在,如果不存在才会新建一个值。比如,如果你调用Symbol.for("cat")30次,每次都会返回同一个Symbol值,但是调用Symbol("cat")30次,会返回30个不同的Symbol值。
var a=Symbol("a")//返回一个唯一的标记
var b=Symbol.for("b")//返回一个登记在Symbol全局表中的标记,
Symbol.keyFor(b)//复查其字符值.
作为属性名的Symbol
由于每一个Symbol值都是不相等的,这意味着Symbol值可以作为标识符,用于对象的属性名,就能保证不会出现同名的属性。这对于一个对象由多个模块构成的情况非常有用,能防止某一个键被不小心改写或覆盖。
var mySymbol = Symbol();
var a = {};a[mySymbol] = 'Hello!';// 第一种写法
var a = {[mySymbol]: 'Hello!'};// 第二种写法
var a = {};Object.defineProperty(a, mySymbol, { value: 'Hello!' });// 第三种写法
a[mySymbol] // "Hello!"// 以上写法都得到同样结果
内置的Symbol值
除了定义自己使用的Symbol值以外,ES6还提供了11个内置的Symbol值,指向语言内部使用的方法。
Symbol.hasInstance
对象的Symbol.hasInstance属性,指向一个内部方法。当其他对象使用instanceof运算符,判断是否为该对象的实例时,会调用这个方法。比如,foo instanceof Foo在语言内部,实际调用的是Foo[Symbol.hasInstance](foo)。
class MyClass {  [Symbol.hasInstance](foo) {return foo instanceof Array;}}
[1, 2, 3] instanceof new MyClass() // true
上面代码中,MyClass是一个类,new MyClass()会返回一个实例。该实例的Symbol.hasInstance方法,会在进行instanceof运算时自动调用,判断左侧的运算子是否为Array的实例。
下面是另一个例子。
class Even {static [Symbol.hasInstance](obj) {return Number(obj) % 2 === 0;}}
1 instanceof Even // false
2 instanceof Even // true
12345 instanceof Even // false
  1. JSON.stringify
    该方法无法识别undefinedSymbolfunction,会跳过他们,如果无法跳过就会转化成null.
    特别的如果存在循环引用的数据,会直接报错.
    额外的如果要打包的对象中有toJSON()方法,那么会调用这个方法获得的值作为打包的值.
var a = {
val: [1,2,3],
// probably correct!
toJSON: function(){
return this.val.slice( 1 );
}
};
var b = {
val: [1,2,3],
// probably incorrect!
toJSON: function(){
return "[" +
this.val.slice( 1 ).join() +
"]";
}
};
JSON.stringify( a ); // "[2,3]"
JSON.stringify( b ); // ""[2,3]""
  1. 剩下的明天再写,晚安
原文地址:https://www.cnblogs.com/always-naive/p/5933815.html