有道

君子爱才,取之有道


  • 首页

  • 分类

  • 归档

  • 标签

  • 公益404

a pixel is not a pixel is not a pixel

发表于 2016-07-01   |  

原文A pixel is not a pixel is not a pixel

  • 现在我正在深入研究移动端中跨浏览器手机的宽和高,得出的结论是在99%的情况下,这些因素不会影响到正常的web开发
  • 剩余的1%变得非常诡异,我期望苹果公司通过假如一个像素层来解决这个1%引起的问题
  • 开始之前,我先提示下:因为这些因素对那些我忽视的正规屏幕尺寸并不重要,并且我没有认真的去研究过展示、像素密度等其他复杂概念。所以,接下的内容我可能用错了很多专业术语,多多包涵。

Web开发者需要什么

  • 我并不知道web开发者真正感兴趣的是什么,但是我知道他们需要CSS像素单位。就是在CSS表达式中声明的:width: 300px 或者是 font-size: 14px;
  • CSS像素和设备像素密度没有任何关系,也跟即将产生的中间层没有任何关系。他们本质上是专门为我们web开发者创造的抽象构造。
  • 我们可以用zoom操作来做简单说明。当用户放大的时候,一个width:300px的元素占据了更大的屏幕,这使得被放大的元素在设备(物理)像素上就变得越来越宽。zoom的效果完全是通过尽可能的扩展CSS像素产生的,然而此时该元素的CSS像素值仍是300px。
  • 当zoom效果达到100%时,一个CSS像素等于一个设备像素(尽管中间层会替代设备像素层)我得说明下zoom 100%对于web开发者来说没有任何意义,Zoom层级对我们不重要,我们要关心的是适配当前屏幕需要多少CSS像素。
  • 我们想想当用户zoom操作时到底发生了什么?当用户缩小时,CSS像素变小,此时一个设备像素重叠了更多的CSS像素。当用户放大时,CSS像素变大,此时一个设备像素重叠更少的CSS像素。
  • 这样我们的width:300px元素的实际CSS像素总是300,另外由zoom因素决定多少设备像素呈现一个CSS像素。
  • 这种机制不会改变,如果改变了,所有iPhone网站会严重失控,苹果公司肯定不会让这一切发生的。
  • 因此,完全适配的网站扔展示980px,此时我们并不关心多少设备像素来呈现980px。

解决方案

  • <meta name=\”viewport\” width=\”device-width\”>
  • media query device-width
  • 以上两种方案都作用于设备像素,而不是CSS像素,因为他们的上下文是网页,不是CSS内部运行环境。

media query

  • device-width代表设备的宽度。
  • width代表页面的宽度。
    1
    2
    3
    4
    5
    6
    /*正常范围宽300*/
    div.sidebar { width: 300px;}
    /*小于320px设定宽100*/
    @media all and (max-device-width: 320px){
    div.sidebar{ width: 100px}
    }

meta tag

  • 一般来说meta标签更有用。这起先是由苹果发布的属性,后来被许多移动浏览器实现,让layout viewport适配设备屏幕更容易。
  • 什么是Layout Viewport? 浏览器用它来计算元素的展示比例(CSS像素),比如div.sidebar{width: 20%},Layout Viewport总是比设备像素大一些。
  • 如果你添加了meta标签,layout viewport的宽度会限制在设备像素内:iPhone 是320
  • 即使你的页面小到足以适配屏幕,那也会有影响。应该加上标签,让文字适配当前屏幕。

other

  • dips: 谷歌提出一个概念,device-independent pixels,CSS像素作用于这一层

Proxy-ES6

发表于 2016-06-30   |  
  • Proxy用于修改某些操作的默认行为,等同于在语言层面做出修改,所以属于一种“元编程”(meta programming),即对编程语言进行编程。
    Proxy可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。Proxy这个词的原意是代理,用在这里表示由它来“代理”某些操作,可以译为“代理器”。
1
2
3
4
5
6
7
8
9
10
11
12
13
//ES6生成Proxy实例
var proxy = new Proxy(target, handler);

var obj = new Proxy({}, {
get: function (target, key, receiver) {
console.log(`getting ${key}!`);
return Reflect.get(target, key, receiver);
},
set: function (target, key, value, receiver) {
console.log(`setting ${key}!`);
return Reflect.set(target, key, value, receiver);
}
});
  • 要使得Proxy起作用,必须针对Proxy实例(上例是proxy对象)进行操作,而不是针对目标对象(上例是空对象)进行操作;如果handler没有设置任何拦截,那就等同于直接通向原对象。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    var target = {};
    var handler = {};
    var proxy = new Proxy(target, handler);
    proxy.a = 'b';
    target.a // "b"
    //技巧:将Proxy对象,设置到object.proxy属性,从而可以在object对象上调用
    var object = { proxy: new Proxy(target, handler) };
    //Proxy实例也可以作为其他对象的原型对象
    var proxy = new Proxy({}, {
    get: function(target, property) {
    return 35;
    }
    });

    let obj = Object.create(proxy);
    obj.time // 35

    //可以进行多操作拦截
    var handler = {
    get: function(target, name) {
    if (name === 'prototype') {
    return Object.prototype;
    }
    return 'Hello, ' + name;
    },

    apply: function(target, thisBinding, args) {
    return args[0];
    },

    construct: function(target, args) {
    return {value: args[1]};
    }
    };

    var fproxy = new Proxy(function(x, y) {
    return x + y;
    }, handler);
    fproxy(2,20);//apply ==> 2
    new fproxy(1,11);//construct ==> {value: 11}
    fproxy.hello;//get ==> Hello, hello
  • Proxy支持的拦截操作如下

    • get(target, propKey, receiver)拦截对象属性的读取,比如proxy.foo和proxy[‘foo’],返回类型不限。最后一个参数receiver可选,当target对象设置了propKey属性的get函数时,receiver对象会绑定get函数的this对象。
    • set(target, propKey, value, receiver)拦截对象属性的设置,比如proxy.foo = v或proxy[‘foo’] = v,返回一个布尔值。
    • has(target, propKey)拦截propKey in proxy的操作,以及对象的hasOwnProperty方法,返回一个布尔值。
    • deleteProperty(target, propKey)拦截delete proxy[propKey]的操作,返回一个布尔值。
    • ownKeys(target)拦截Object.getOwnPropertyNames(proxy)、Object.getOwnPropertySymbols(proxy)、Object.keys(proxy),返回一个数组。该方法返回对象所有自身的属性,而Object.keys()仅返回对象可遍历的属性。
    • getOwnPropertyDescriptor(target, propKey)拦截Object.getOwnPropertyDescriptor(proxy, propKey),返回属性的描述对象
    • defineProperty(target, propKey, propDesc)拦截Object.defineProperty(proxy, propKey, propDesc)、Object.defineProperties(proxy, propDescs),返回一个布尔值。
    • preventExtensions(target)拦截Object.preventExtensions(proxy),返回一个布尔值。
    • isExtensible(target)拦截Object.isExtensible(proxy),返回一个布尔值。
    • setPrototypeOf(target, proto)拦截Object.setPrototypeOf(proxy, proto),返回一个布尔值。
    • apply(target, object, args)拦截Proxy实例作为函数调用的操作,比如proxy(…args)、proxy.call(object, …args)、proxy.apply(…)。
    • construct(target, args)拦截Proxy实例作为构造函数调用的操作,比如new proxy(…args)。
  • 各拦截操作实战用途如下

    • get 可以在读取不存在的属性时抛出一个错误,而不是仅仅返回无意义的undefined;可以在返回之前做逻辑处理,比如实现数组负数索引取值;可以创建链式调用。
    • set 可以用来实施更新DOM
    • has 可以对in运算符做特殊处理,如不让带大写A的属性被in发现;has方法拦截的是HasProperty操作,而不是HasOwnProperty操作,即has方法不判断一个属性是对象自身的属性,还是继承的属性。for…in操作内部也是用到HasProperty操作,所以has方法在for…in循环时也会生效。
    • construct方法返回的必须是一个对象,否则会报错。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      //在返回真正的对象前可以加以处理,但返回值必须是对象
      var p = new Proxy(function() {}, {
      construct: function(target, args) {
      console.log('called: ' + args.join(', '));
      return { value: args[0] * 30 };
      }
      });

      new p(10).value
      // "called: 10"
      // 300
    • getPrototypeOf用来拦截object.getPrototypeOf()运算符,以及Reflect.getPrototypeOf,instanceof运算符,Object.prototype.isPrototypeOf

  • Proxy.revocable(),Proxy.revocable方法返回一个对象,该对象的proxy属性是Proxy实例,revoke属性是一个函数,可以取消Proxy实例。上面代码中,当执行revoke函数之后,再访问Proxy实例,就会抛出一个错误。
    1
    2
    3
    4
    5
    6
    7
    8
    let target = {};
    let handler = {};

    let {proxy, revoke} = Proxy.revocable(target, handler);
    proxy.foo = 123;
    proxy.foo //123
    revoke();
    proxy.foo // TypeError : Revoke

Pixel puzzle

发表于 2016-06-22   |  
  • pt && px
    PPI=(√(X²+Y²))/ Z (X:长度像素数;Y:宽度像素数;Z:屏幕尺寸)

Reflect-ES6

发表于 2016-06-22   |  
  • Reflect 对象与Proxy对象一样,也是ES6为了操作对象而提供的新API。
  • 将Object对象的一些明显属于语言内部的方法(比如Object.defineProperty),放到Reflect对象上。现阶段,某些方法同时在Object和Reflect对象上部署,未来的新方法将只部署在Reflect对象上。
  • 修改某些Object方法的返回结果,让其变得更合理。比如,Object.defineProperty(obj, name, desc)在无法定义属性时,会抛出一个错误,而Reflect.defineProperty(obj, name, desc)则会返回false。
  • 让Object操作都变成函数行为。某些Object操作是命令式,比如name in obj和delete obj[name],而Reflect.has(obj, name)和Reflect.deleteProperty(obj, name)让它们变成了函数行为。
  • Reflect对象的方法与Proxy对象的方法一一对应,只要是Proxy对象的方法,就能在Reflect对象上找到对应的方法。这就让Proxy对象可以方便地调用对应的Reflect方法,完成默认行为,作为修改行为的基础。也就是说,不管Proxy怎么修改默认行为,你总可以在Reflect上获取默认行为。
  • Reflect方法清单
    • Reflect.apply(target,thisArg,args)
    • Reflect.construct(target,args)
    • Reflect.get(target,name,receiver)
    • Reflect.set(target,name,value,receiver)
    • Reflect.defineProperty(target,name,desc)
    • Reflect.deleteProperty(target,name)
    • Reflect.has(target,name)
    • Reflect.ownKeys(target)
    • Reflect.isExtensible(target)
    • Reflect.preventExtensions(target)
    • Reflect.getOwnPropertyDescriptor(target, name)
    • Reflect.getPrototypeOf(target)
    • Reflect.setPrototypeOf(target, prototype)

callee-caller

发表于 2016-06-20   |  

callee

  • callee是arguments的属性成员,返回正被执行的 Function 对象,也就是所指定的 Function 对象的正文
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    function calleeLengthDemo(arg1, arg2) { 
    alert(arguments.callee.toString());
    if (arguments.length == arguments.callee.length) {
    window.alert("验证形参和实参长度正确!");
    return;
    } else {
    alert("实参长度:" + arguments.length);
    alert("形参长度: " + arguments.callee.length);
    }
    }
    calleeLengthDemo(1); //实参长度:1,形参长度:2
    //=============================================//
    //应用于匿名函数调用自身场景
    var fn=(function(n){
    if(n>0) return n+arguments.callee(n-1);
    return 0;
    })(10);
    alert(fn)

caller

  • functionName.caller 返回调用者
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    function caller() { 
    if (caller.caller) {
    alert(caller.caller.toString());
    } else {
    alert("函数直接执行");
    }
    }
    function handleCaller() {
    caller();
    }
    handleCaller(); //handleCaller
    caller(); // 函数直接执行

Symbol-ES6

发表于 2016-06-05   |  
  • symbol 可以转换成字符串类型、布尔类型,不能转换成数值。

    1
    2
    3
    4
    var s = Symbol('a')
    s.toString()// Symbol(a)
    !s // false
    Number(s) // TypeError
  • symbol定义时不能用.运算符

    1
    2
    3
    4
    5
    6
    var mysymbol = Symbol()
    var a = {}
    a.mysymbol = 'hello'
    //因为点运算符后面总是字符串,所以不会读取mysymbol作为标识名所指代的那个值,导致a的属性名实际上是一个字符串,而不是一个Symbol值
    a[mysymbol] //undefined
    a['mysymbol'] // hello
  • symbol.for(‘string’) 和 symbol(‘string’) 的区别是会在全局环境中搜索 string 是否已经存在,如果没有存在则新建一个值

    1
    2
    3
    4
    5
    6
    7
    8
    9
    var s1 = Symbol.for('a')
    var s2 = Symbol.for('a')

    s1 == s2 //true

    var s3 = Symbol('c')
    var s4 = Symbol('d')

    s3 == s4 //false
  • symbol.keyfor(‘string’) 返回一个已登记的Symbol值,在全局环境中起作用,可以在不同iframe和service worker中起作用

    1
    2
    3
    var s1 = Symbol.for('cc')
    symbol.keyfor(s1) // cc
    symbol.keyfor(s2) // undefined
  • 内置symbol

    • Symbol.hasInstance,foo instance Foo内部是Foo[Symbol.hasInstance](foo)

      1
      2
      3
      4
      5
      6
      7
      class MyClass {
      [Symbol.hasInstance](foo) {
      return foo instanceof Array;
      }
      }

      [1, 2, 3] instanceof MyClass() // true
    • Symbol.isConcatSpreadable 对象是否可以展开

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      //数组对象默认展开
      let arr1 = ['c', 'd'];
      ['a', 'b'].concat(arr1, 'e') // ['a', 'b', 'c', 'd', 'e']

      let arr2 = ['c', 'd'];
      arr2[Symbol.isConcatSpreadable] = false;
      ['a', 'b'].concat(arr2, 'e') // ['a', 'b', ['c','d'], 'e']
      //字面量对象默认收起
      let obj = {length: 2, 0: 'c', 1: 'd'};
      ['a', 'b'].concat(obj, 'e') // ['a', 'b', obj, 'e']

      obj[Symbol.isConcatSpreadable] = true;
      ['a', 'b'].concat(obj, 'e') // ['a', 'b', 'c', 'd', 'e']
    • Symbol.species 指向一个方法,该对象做为构造函数创造实例时,会调用这个方法。

    • Symbol.match 指向一个函数,当执行str.match(myObject)时,如果该属性存在,会调用它,返回该方法的返回值

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      String.prototype.match(regexp)
      // 等同于
      regexp[Symbol.match](this)

      class MyMatcher {
      [Symbol.match](string) {
      return 'hello world'.indexOf(string);
      }
      }

      'e'.match(new MyMatcher()) // 1
    • Symbol.replace 指向一个方法,当该对象被String.prototype.replace调用时,会返回该方法的返回值

    • Symbol.search 指向一个方法,当该对象被String.prototype.search调用时,会返回该方法的返回值
    • Symbol.split 指向一个方法,当该对象被String.prototye.split调用时,会返回该方法的返回值
    • Symbol.iterator 指向该对象默认遍历器方法.对象进行for…of循环时,会调用Symbol.iterator方法,返回该对象的默认遍历器
    • Symbol.toPrimitive

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      let obj = {
      [Symbol.toPrimitive](hint) {
      switch (hint) {
      case 'number':
      return 123;
      case 'string':
      return 'str';
      case 'default':
      // 既可以转成字符串也可以转成数字时为default状态
      return 'default';
      default:
      throw new Error();
      }
      }
      };

      2 * obj // 246
      3 + obj // '3default'
      obj === 'default' // true
      String(obj) // 'str'
    • Symbol.toStringTag 被Object.prototype.toString调用时触发

      1
      2
      3
      4
      5
      6
      7
      class Collection {
      get [Symbol.toStringTag]() {
      return 'x2x3x';
      }
      }
      var x = new Collection();
      console.log(Object.prototype.toString.call(x)) // "[object x2x3x]"
    • Symbol.unscopables 指向一个对象,设置哪些属性可被with环境排除

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      // 没有unscopables时
      class MyClass {
      foo() { return 1; }
      }

      var foo = function () { return 2; };

      with (MyClass.prototype) {
      foo(); // 1
      }

      // 有unscopables时
      class MyClass {
      foo() { return 1; }
      get [Symbol.unscopables]() {
      return { foo: true };
      }
      }

      var foo = function () { return 2; };

      with (MyClass.prototype) {
      foo(); // 2
      }

document-node

发表于 2016-06-01   |  
  • previousSibling,在IE下,会忽略节点间的空白节点(空格、回车和Tab键);在遵循W3C规范的浏览器(Chrome、FireFox、Safari等)下则不会。
  • nextSibling

css-box

发表于 2016-06-01   |  

容器属性

  • box-pack:定义子元素主轴对齐方式:justify-content

    1
    2
    box-pack: start | end | center | justify;
    /*主轴对齐:左对齐(默认) | 右对齐 | 居中对齐 | 左右对齐*/
  • box-align:定义元素交叉轴对齐方式:align-items

    1
    2
    box-align: start | end | center | baseline | stretch;
    /*交叉轴对齐:顶部对齐(默认) | 底部对齐 | 居中对齐 | 文本基线对齐 | 上下对齐并铺满*/
  • box-direction:定义元素显示方向:flex-flow

    1
    2
    box-direction: normal | reverse | inherit;
    /*显示方向:默认方向 | 反方向 | 继承子元素的 box-direction*/
  • box-orient:定义子元素水平或垂直排列:flex-flow

    1
    2
    box-orient: horizontal | vertical | inline-axis | block-axis | inherit;
    /*排列方向:水平 | 垂直 | 行内方式排列(默认) | 块方式排列 | 继承父级的box-orient*/
  • box-lines:定义子元素超出容器是否换行:flex-wrap

    1
    2
    box-lines: single | multiple;
    /*允许换行:不允许(默认) | 允许*/
  • box-flex:定义是否允许子元素伸缩:flex

    1
    2
    box-flex: <value>;
    /*伸缩:<一个浮点数,默认为0.0,即表示不可伸缩,大于0的值可伸缩,柔性相对>*/
  • box-ordinal-group:定义子元素的显示顺序:flex-order

    1
    2
    box-ordinal-group: <integer>;
    /*显示次序:<一个整数,默认为1,数值越小越排前>*/
  • 元素对其方式

    1
    2
    align-self: auto | flex-start | flex-end | center | baseline | stretch;
    /*单独对齐方式:自动(默认) | 顶部对齐 | 底部对齐 | 居中对齐 | 上下对齐并铺满 | 文本基线对齐*/

兼容写法

  • 如果子元素是行内元素,在很多情况下都要使用 display:block 或 display:inline-block 把行内子元素变成块元素(例如使用 box-flex 属性),这也是旧版语法和新版语法的区别之一。
  • 由于旧版语法并没有列入W3C标准,所以这里不用写 display:box ,下面的语法也是一样的。

    1
    2
    3
    4
    5
    6
    7
    .box{
    display: -webkit-box; /* 老版本语法: Safari, iOS, Android browser, older WebKit browsers. */
    display: -moz-box; /* 老版本语法: Firefox (buggy) */
    display: -ms-flexbox; /* 混合版本语法: IE 10 */
    display: -webkit-flex; /* 新版本语法: Chrome 21+ */
    display: flex; /* 新版本语法: Opera 12.1, Firefox 22+ */
    }
  • 子元素轴对齐方式,旧版语法有4个参数,而新版语法有5个参数,兼容写法新版语法的 space-around 是不可用的

    1
    2
    3
    4
    5
    6
    .box{
    -webkit-box-pack: center;
    -moz-justify-content: center;
    -webkit-justify-content: center;
    justify-content: center;
    }
  • 子元素交叉轴对齐方式

    1
    2
    3
    4
    5
    6
    .box{
    -webkit-box-align: center;
    -moz-align-items: center;
    -webkit-align-items: center;
    align-items: center;
    }
  • 子元素的显示方向,可通过 box-direction + box-orient + flex-direction 实现

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
       /*左到右*/
    .box{
    -webkit-box-direction: normal;
    -webkit-box-orient: horizontal;
    -moz-flex-direction: row;
    -webkit-flex-direction: row;
    flex-direction: row;
    }
    /*右到左*/
    .box{
    -webkit-box-pack: end;
    -webkit-box-direction: reverse;
    -webkit-box-orient: horizontal;
    -moz-flex-direction: row-reverse;
    -webkit-flex-direction: row-reverse;
    flex-direction: row-reverse;
    }
    /*上到下*/
    .box{
    -webkit-box-direction: normal;
    -webkit-box-orient: vertical;
    -moz-flex-direction: column;
    -webkit-flex-direction: column;
    flex-direction: column;
    }
    /*下到上*/
    .box{
    -webkit-box-pack: end;
    -webkit-box-direction: reverse;
    -webkit-box-orient: vertical;
    -moz-flex-direction: column-reverse;
    -webkit-flex-direction: column-reverse;
    flex-direction: column-reverse;
    }
  • 是否允许子元素伸缩

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    /*扩展*/
    .item{
    -webkit-box-flex: 1.0;
    -moz-flex-grow: 1;
    -webkit-flex-grow: 1;
    flex-grow: 1;
    }
    /*收缩*/
    .item{
    -webkit-box-flex: 1.0;
    -moz-flex-shrink: 1;
    -webkit-flex-shrink: 1;
    flex-shrink: 1;
    }

jQuery-Deferred

发表于 2016-05-31   |  
  • jQuery 1.5.0 之前的jQuery调用ajax语法
1
2
3
4
5
6
7
8
9
  			$.ajax({
     url: "test.html",
    success: function(){
       alert("success!");
     },
     error:function(){
       alert("error!");
     }
   });
  • jQuery 1.5.0 新增Deferred对象后ajax语法
1
  			$.ajax({url: "test.html"}).done(function(){alert("success!")}).fail(function(){alert("error!")});
  • 多次回调
1
$.ajax({url: "test.html"}).done(function(){alert("success!")}).fail(function(){alert("error!")}).done(function(){alert("success again")});
  • 为多个事件制定一个回调参数
1
2
3
$.when($.ajax({url:'1t.html'}),$.ajax({url:'2t.html'})).
done(function(){alert('all success')}).
fail(function(){alert('not all success')});
  • 普通函数的回调参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//判断是否支持webP格式图片
function hasWebP(){
var rv = $.Deferred();
var img = new Image();
img.onload = function (){ return rv.resolve();}
img.onerror = function(){ return rv.reject();}
//img.src="http://baidu.com/1.jpg";
img.src="http://musicdata.baidu.com/data2/pic/39817702/39817702.jpg";
$('div').append(img);
return rv.promise();
}
$(function(){
//then(done,fail)
hasWebP().then(function(){console.log(1)},function(){console.log(2)});
})
  • Deffered可以接受一个函数名参数
1
2
3
4
5
6
7
8
9
10
11
12
  function func(rv){
//rv是Deferred对象
    var tasks = function(){
      alert("done!");
rv.resolve();
    };
    setTimeout(tasks,3000);
return rv.promise();
}
$.Deferred(func)
  .done(function(){ alert("success!"); })
  .fail(function(){ alert("error!"); });
  • always方法,执行完done,fail后执行
1
2
3
4
 $.Deferred(func)
  .done(function(){ alert("success!"); })
  .fail(function(){ alert("error!"); })
.always(function(){console.log('end');})

Object-ES6

发表于 2016-05-22   |  
  • 属性简写:允许只写对象属性名,不写属性值

    1
    2
    3
    4
    let foo = 'hello'
    let bar = {foo} // bar.foo = 'hello'
    function x(my,other){ return {my,other}}
    let o = x(1,2)// o.my = 1 , o.other = 2
  • 方法简写

    1
    2
    3
    4
    5
    6
    let obj = {
    method(){
    return "hello~"
    }
    }
    console.log(obj.method()) // hello~
  • 方括号定义对象变量

    1
    2
    3
    4
    5
    //ES5
    var bar = {"foo":"hello"}
    //ES6
    let f = "foo"
    let bar = {[f]:'hello'} // bar.foo = hello
  • Object.is

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Object.defineProperty(Object, 'is', {
    value: function(x, y) {
    if (x === y) {
    // 针对+0 不等于 -0的情况
    return x !== 0 || 1 / x === 1 / y;
    }
    // 针对NaN的情况
    return x !== x && y !== y;
    },
    configurable: true,
    enumerable: false,
    writable: true
    });
  • Object.assin 合并可枚举对象

    • 为对象添加属性
    • 为对象添加方法
    • 克隆对象
    • 合并多个对象
    • 为属性指定默认值
  • Object.getOwnPropertyDescriptor 属性的可枚举性
    • ES5会有三个操作忽略enumerable为false的属性
      • for…in循环:只遍历对象自身的和继承的可枚举的属性
      • Object.keys():返回对象自身的所有可枚举的属性键名
      • JSON.stringify:只串行化对象自身的可枚举的属性
    • ES6新增会忽略enumerable为false的属性
      • Object.assign():只拷贝对象自身可枚举的属性
      • Reflect.enumerate():返回所有for…in循环会遍历的属性
1…345…7
wangtuda

wangtuda

新一天新积累
I Belive I Can.

64 日志
1 分类
55 标签
© Thu Mar 24 2016 08:00:00 GMT+0800 (CST) - 2017 wangtuda
由 Hexo 强力驱动
主题 - NexT.Pisces