zoukankan      html  css  js  c++  java
  • ECMA-Script5

    严格模式

    所谓严格模式,从字面上就很好理解,即更严格的模式
    在这种模式下执行,浏览器会对JS的要求更苛刻。

    举例: 
    function m1(){
         max = 100;
    }
    m1();
    alert(max); //由于max没有var声明,因此max会变成全局变量

    但是在严格模式下:
    function m1(){
        "use strict";
        max = 100;
    }
    m1();
    alert(max);
    Uncaught ReferenceError: max is not defined

    不加var报错
    with被禁用
    callee 被禁用
    禁止delete window对象属性
    八进制被禁用
    arguments与形参不同步
    this不允许指向window

    所以不要轻易在全局范围开头增加 "use strict" 声明
    建议在作用域内部使用


    bind方法

    Jquery里面也有bind方法,它大概长这个样子:
    $("#btn").bind("click",function(){
         alert(this.id);
    })

    或许你真的从来没有认真的想过,为什么我们的匿名函数里会有this关键字?
    当你点击的时候,#btn的ID就被弹了出来。this为什么会指向了#btn???

    举例:
    btn.onclick = function(){
         setTimeout(function(){
                  this.innerText = "已点击"; 
         }.bind(this),2000)
    }
    我们都知道定时器的匿名函数里不能写this,它会指向window
    但有了bind方法以后,我们可以随意设定this 的指向

    貌似在字面量编程风格中,可能好处就更明显

    举例:
    var Engine = {
         body : $("#main"),
         setBackground : function(){
                 this.body.css("background","url(xxxx.png) repeat-y");
         }
         loadEvents : function(){
             $("#cb").click(function(){  //我们给某个元素添加单击事件
                  this.setBackground("");  //但实际操作却是Engine本身,从结构上做到了解耦
              }.bind(this)); 
         },
         init : function(){
              //.......
              this.loadEvents();
              return this;
         }
    }


    JSON.parse / JSON.stringify

    我们从eval方法,过渡到了JSON.parse(),去除了eval方法注入代码的风险

    JSON提供了两个方法
    JSON.parse,解析一个字符串,并返回对象

    举例:
    var obj = JSON.parse('{"id":3, "value":30}');
    obj.value; //30

    注意:idvalue都使用了双引号,否则解析不正确

    JSON.stringify,解析一个对象,并返回字符串

    举例:
    var obj = { id: 3, value: 30 };
    JSON.stringify(obj);  //'{"id":3, "value":30}'

    扩展: 额外的处理函数
    var obj = JSON.parse('{"id":3, "value":30.99}');
    obj.value; //30.99
    如果你想四舍五入
    JSON.parse('{"id":3, "value":30.99}', function(key, val){
         if(typeof val == "string"){
              return Math.round(Number(val));
         } else {
              return Math.round(val);
         }
    })

    最终结果: obj.value // 31


    数组的额外方法

    indexOf
    [2, 5, 7, 3, 5].indexOf(5)  //返回1   
    无法判定对象数组,这时候可以用some
     

    forEach
    ["a", "b", "c", "d", "e"].forEach(function(item, index, array){
         //跟jquery几乎一样,除了参数顺序
         //item表示当前遍历的元素,index表示下标,array表示数组本身
         console.log(item);
    });

    其实也可以更简单:
    ["a", "b", "c", "d", "e"].forEach(alert);

    注意:
    ["a", "b", "c", "d", "e"].forEach(console.log);    //会出现Uncaught TypeError: Illegal invocation(…),forEach(function(){},this)
    因为执行上下文非法导致的,我们需要指定一下上下文:
    ["a", "b", "c", "d", "e"].forEach(console.log, console);  //正确执行,forEach(function(item){console.log(item)},console)

    map 映射,遍历---->操作----->返回
    var newarr = [1,2,3,4,5].map(function(item, index, array){
         return item+2;  //
    })
    newarr;
    结果: [3, 4, 5, 6, 7]


    reduce 归并

    [1,2,3,4].reduce(function(pre, next, index, array){
         //参数中的x和y,代表了之前的处理结果和下一个元素
         return x+y; //return的结果会赋值给下一个函数的x参数
    });
    结果 : 10
    		var list=['a',1,2,3,4,5];
    		list.reduce=function(callback){//模拟实现
    			var _tmp=this[0];
    			for(var i=1;i<this.length;i++){
    				_tmp=callback(_tmp, this[i], i, this)
    					
    			}
    			return _tmp;
    			
    			
    		}
    		var new_value=list.reduce(function(pre, next, index, array){
    			return pre*next;
    		
    		});
    		console.log(new_value);



    filter 过滤
    var res = [88,69,92,77,90,96,98,99].filter(function(item, index, array){
         return item>80;//找出所有大于80的元素
    });
    结果:[88,92,90,96,98,99]


    		var list=[1,2,3,4,5];
    		list.filter=function(callback){//模拟实现
    			var _tmp=[];
    			for(var i in list){
    				if(callback(this[i],i,this))
    					_tmp.push(this[i]);	
    			}
    			return _tmp;
    			
    			
    		}
    		var newList=list.filter(function(item,index,arr){
    			return index%2==0?true:false;
    		
    		});
    		console.log(newList);


    some 某些   (我觉得叫anyone更适合)
    if(["yt","hr","wc","jk"].some(function(item){
         //判断数组中是否存在yt?
         return item=="yt";
    })){
         alert("好的!");
    }

    跟过滤器好像差不多,但它只会返回一个布尔类型,如果匹配成功,则返回true
    而且一旦匹配成功,后面就不再遍历了,如果没有匹配成功,最后返回false
    可以用来做一些检测

    every
    ["ab","bc","cd","xy","zz"].every(function(item){
         return typeof item === "string";
    });
    跟some一样,但要求每一项都符合,才返回true
    有一项不合格就返回false

    String的trim方法

    "   abc   ".trim();
    首尾去空格
    "abc"

    Object.keys() /Object.values()
    用于获取对象的属性和对象的值

    对于不可枚举的属性无效

    var obj = {id:3, age: 20};

    Object.keys(obj);     // ["id","age"]
    Object.values(obj);   // [3, 20]

    Object.defineProperty(obj, "age", {
        enumerable : false
    });

    Object.keys(obj);     // ["id"]
    Object.values(obj);   // [3]

    Object.create 

    创建对象的一种新形式:

    var father = {
         money: 999999
    }

    var son = Object.create(father);

    son.money; //999999
    //不要误以为这是在复制对象,实际上这是在继承,因为fahter对象的内容被存入了son对象的原型当中

    举例:
    function Father(){
         this.name = "王健林";
         this.age = 60;
    }
    Father.prototype = {
         wanda : function(){
              return "$99999999999";
         }
    }
    //以前的写法,大概是这样:
    //Son.prototype = new Father();
    //缺点很明显就是,连名字和年龄都继承了,其实我们并不想要这些

    //下面的写法,带来了一定的好处,Son的原型的原型是Fahter的原型,同样是原型链继承的效果。
    Son.prototype = Object.create(Father.prototype);
    function Son(){    
         this.name = "王思聪";
         this.age = 30;
    }
    new Son().wanda();

    //要注意这个方法不能实现对象拷贝,因为这里是原型的赋值,并且生成了新对象,不是简单的属性复制

    例如:
    var a = {
         text1 : "abc"
    }
    var b = {
         text2 : "def"
    }
    b = Object.create(a); //结果b虽然继承了a,但原有内容被覆盖了!

    b.text1; //abc
    b.text2; //undefined

    解决办法如下:
    var b = Object.create(a, {
         text2 : {
             value : "def" 
         }
    })

    Object.defineProperty

    对于属性的定义和拦截,讲个实用的例子吧
    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
            <title></title>
        </head>
        <script src="js/jquery-1.8.3.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            "use strict";
            window.onload = function(){
                QF.appInit();
            }
            var QF = {
                scope : {},
                appInit(){
                    this.htmlstr = document.body.innerHTML
                    this.app = $("[qf-app]").get(0);
                    this.inputlist = $(this.app).find("[qf-model]").get();

                    for(let inpt of this.inputlist){
                        if(inpt.nodeName=="INPUT" && inpt.type == "text"){
                            let modelname = inpt.getAttribute("qf-model");
                            let vm = {
                                viewlist : $(QF.app).find(":contains('"+"{{"+modelname+"}}')")
                            };
                            //view model的修改监听
                            Object.defineProperty(vm, "value", {
                                configurable: true,
                                enumerable: true,
                                set : function(val){
                                    this.viewlist.each(function(){
                                        $(this).html(val);                                   
                                    });
                                }
                            });
                            this.scope[modelname] = vm;

                            //输入框的修改监听
                            Object.defineProperty(HTMLInputElement.prototype, "value", {
                                configurable: true,
                                enumerable: true,
                                set: function(val){
                                    console.log(val, inpt.value);
                                    QF.scope[this.getAttribute("qf-model")].value = this.value;
                                }
                            })
                        }
                    }
                    $("input").bind("input",function(){
                        this.value = this.value;
                    });
                },
            }
        </script>
        <body>
            <div qf-app>
                <input qf-model="yourname" type="text"/>
                <input qf-model="hername" type="text"/>
                <p>{{yourname}}</p>
                <p>{{yourname}}</p>
                <p>{{hername}}</p>
            </div>
        </body>
    </html>


    上面这段代码是一个简单的View — > Model  >  View的 数据绑定

    defineProperty函数最大的好处就是可以自定义属性的读写权限,以及遍历权限(可枚举性)
    Object.defineProperty(stu, 'score', {
         writeable: true,  //表示该属性是否可写
         enumerable: true,  //表示该属性是否可以枚举(遍历)    
         configurable: true,  //表示该属性是否可删除,以及是否可配置, 比如writeable能不能被修改 
         set: function(val){
              //当属性被赋值时,做一些拦截动作,例如将数据同步到view
         }
         get: function(){
              //当属性被获取时,做一些拦截动作,例如权限检查之类的
         }
    });


    Object.getPropertyOf

    用来获取原型对象,可以充当JAVA中的super来使用

    function Person(){
        this.method1 = function(){     alert(1);     }
    }

    Man.prototype = new Person();//原型继承
    function Man(){
        this.method1 = function(){
            //相当于this.__proto__.method1();
            Object.getPrototypeOf(this).method1();
        }
    }

    var man = new Man();  
    man.method1();





























  • 相关阅读:
    Remote API(RAPI)之 文件管理
    vue前端框架

    托马斯彩色回旋
    VUE?
    cookie与session
    ajax前后端分离
    djangoIII
    Django少年
    django三板斧
  • 原文地址:https://www.cnblogs.com/fanlinqiang/p/7741231.html
Copyright © 2011-2022 走看看