一般人不清楚的JavaScript概念

来源:互联网 发布:帖吧爆吧软件 编辑:程序博客网 时间:2024/04/29 16:35

注:以下部分代码或术语涉及ECMAScript 6。

1. literal

literal(字面量)即开发者写的,可直接被解析器识别,不必显式依赖API创建的量。如:

  • 数字literal:123, 0b1111011, 0o173, 0x7B
  • 字符串literal:"123", `12{2+1}`
  • 数组literal:[1,2,8]
  • 对象literal:{A:1,B:2,C:8}
  • 正则表达式literal:/^\d+(?:\.\d+)?$/
  • 其他literal:true, false, null

2. IIFE

还记得为了闭包(closure)而编写的声明即执行的函数表达式吗?这种函数表达式是IIFE,读作[iffy]。

var chars=//charCode为0x20,0x21,...,0x7F的一组字符组成的字符串,由以下IIFE表示(function(){    var a=[];    for(let i=0x20;i<0x80;i++){        a.push(i);    }    return String.fromCharCode.apply(String,a);})();

3. property and expando

property对于一般JavaScript开发者来说,熟悉而又陌生:
一个object的property含property key和property descriptor两部分。
property key分string和symbol两种。
property descriptor分data descriptor和accessor descriptor两种。
data descriptor有固定的value,而accessor descriptor有getter与/或setter。
property descriptor中的enumerable,configurable分别表示property是否可枚举,是否可重定义。

expando是property的一个形容词,指在规范之外扩展的,仅供实现者内部使用的。
对于jQuery而言,jQuery.fn属性可算作一个expando property。

举例:

var lengthExpando=Symbol.for("length");function ArrayLike(){    var length=0;    // ...    Object.defineProperty(        this,        lengthExpando,// symbol as a property key        {enumerable:false,configurable:true,value:length}// data descriptor    );// define an expando property    Object.defineProperty(        this,        "length",// string as a property key        {            enumerable:false,            configurable:true,            get:function(){                return this[lengthExpando];            },            set:function(value){                var num=+value;                var len=num>>>0;                if(len!=num){                    throw new RangeError("Invalid length");                }                // ...                this[lengthExpando]=len;            }        }// accessor descriptor    );// define a spec-defined property}

4. mixin

与plugin可被安装到兼容的宿主程序的概念类似,mixin是一个class/object,它的属性/方法可动态复制到其他适配的class/object。
举例:

// define a mixin which is compatible with any Array-like class or objectvar ArrayLikePrototype={    get firstElement(){        var index=0;        if(index<this.length){            return this[index];        }        //return undefined;    },    getFirstElement(){        var index=0;        if(index<this.length){            return this[index];        }        //return undefined;    },    get lastElement(){        var index=this.length-1;        if(index>-1){            return this[index];        }        //return undefined;    },    getLastElement(){        var index=this.length-1;        if(index>-1){            return this[index];        }        //return undefined;    },    // ...};// mix `ArrayLikePrototype` in `NodeList.prototype`Object.defineProperties(NodeList.prototype,Object.getOwnPropertyDescriptors(ArrayLikePrototype));// mix `ArrayLikePrototype` in `HTMLCollection.prototype`Object.defineProperties(HTMLCollection.prototype,Object.getOwnPropertyDescriptors(ArrayLikePrototype));//so that `document.children.firstElement` will be document.children[0]// or even mix `ArrayLikePrototype` in `Array.prototype`Object.defineProperties(Array.prototype,Object.getOwnPropertyDescriptors(ArrayLikePrototype));//so that `[1,2,3].lastElement` will be 3, and `[1,2,3].getLastElement()` will be 3 too

5. shim and polyfill

shim 是为修正运行环境API而编写的代码。如:

// shim Window#setTimeout()if(document.documentMode==9&&!Object.prototype.hasOwnProperty.call(window,"setTimeout")){    var WindowSetTimeout=Window.prototype.setTimeout;    Window.prototype.setTimeout=function setTimeout(callback, delay){        if(arguments.length<3||typeof callback!="function")            return WindowSetTimeout.call(this, callback, delay);        var args=Array.prototype.slice.call(arguments, 2);        return WindowSetTimeout.call(this, function(){            callback.apply(this, args);        }, delay);    };}//shim window.Eventif(document.documentMode>8&&typeof window.Event=="object"){    var nativeEvent=window.Event;    var shimedEvent=function Event(type/*,eventInit*/){        if(!(this instanceof Event))            throw new TypeError("Failed to construct 'Event': Please use the 'new' operator, this DOM object constructor cannot be called as a function.");        if(arguments.length===0)            throw new TypeError("Failed to construct 'Event': An event type must be provided.");        var event=document.createEvent("Event"),            eventInit={bubbles:false,cancelable:false},            p=Object.assign(eventInit,arguments[1]);        event.initEvent(type,p.bubbles,p.cancelable);        return event;    };    shimedEvent.prototype=nativeEvent.prototype;    window.Event=shimedEvent;}

polyfill是为填补运行环境缺失的功能而提供的变通实现代码。如:

// polyfill Object.assign()if(typeof Object.assign!="function"){    Object.assign=function assign(object,source){        var to,from,sources,nextSource,i,j,len,keys,key;        //#1        if(object==null)            throw new TypeError("Cannot convert "+object+" to Object");        to=Object(object);        //#3        if(arguments.length===1)            return to;        //#4        sources=Array.prototype.slice.call(arguments,1);        //#5        for(i=0; i<sources.length; i++){            //#a            nextSource=sources[i];            if(nextSource==null){continue;}            //#b            from=Object(nextSource);            //#d            keys=Object.keys(from);            //#e            len=keys.length;            //#f            for(j=0;j<len;j++){                key=keys[j];                to[key]=from[key];            }        }        //#6        return to;    };}// polyfill HTMLElement#hiddenif(typeof document.documentElement.hidden!="boolean"){    Object.defineProperty(HTMLElement.prototype,"hidden",{        get:function getHidden(){            return this.getAttribute("hidden")!=null;        },        set:function setHidden(v){            if(v)                this.setAttribute("hidden", "");            else                this.removeAttribute("hidden");        }    });}

6. SemVer

越扯越远,这一条似乎与JavaScript不相关。

平时我们看到的一些软件库文件名如jquery-2.1.3.js,知道其中的版本号2.1.3遵循X.Y.Z,但XYZ每部分的含义,升级规则和比较/排序规则却又不清楚。
为了定义一个通用的版本号标准,GitHub联合创始人Tom Preston-Werner编写了SemVer(Semantic Versioning)规范。
SemVer 2.0.0规范定义的版本号的格式如下:
major . minor . patch [ - pre] [ + build]
一个SemVer版本号不仅仅代表着一个独特的版本,还牵涉到其背后一系列的排序/升级/关联/筛选规则。

7. vanilla

这里的vanilla指寻常的,无特色的。vanilla js用中文说即纯手工编写,未用到第三方框架的js。

VanillaJS是一个没有可运行代码的JavaScript框架,通常被用作愚人节玩笑。它列举一些直接调用原生API而不必借助框架的实践方式,并突出这些寻常代码相对基于框架调用的代码所带来的性能优势,其思想有种道家无为的意味。但恰恰其他框架在试图证明使用框架后相对VanillaJS所带来的兼容/易用优势。

to be continued

更多见 MDN词汇表

0 0
原创粉丝点击