es6篇

发表于 2017-05-02

es6学习

let const

let 局部{}内有效,只在它所在的代码块有效 暂时性死区的本质就是,只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量 我们通常用let和const来声明,let表示变量、const表示常量。let和const都是块级作用域。怎么理解这个块级作用域? 1、在一个函数内部 2、在一个代码块内部 说白了 {}大括号内的代码块即为let 和 const的作用域。 [^_^]:more

Promise

写同步代码的方式来完成异步需求。

var a=0;
var promise = new Promise(function(resolve, reject) {
 if (a==0){
   // console.log(resolve(a))
 resolve("iiiiiii");

 } else {
 reject("error");
 }
}).catch(function(err){
  console.log("catch");
 });
//此处的catch可以捕捉上面的错误
promise.then(function(value) {
  console.log(value)
 console.log('success')
 return {"p":"pppp"}

}, function(value) {
 // failure
 console.log('fail')
 console.log(value);


}).then(function(value) {
  console.log(value)
 console.log('success')

}, function(value) {
 // failure
 console.log('fail')
 console.log(value);


}).catch(function(err){
  console.log("catch");
  console.log("error");
 });
 //此处的catch可以捕捉then里面的错误。上一个的return 值作为下一个then的参数。第一个then的参数来自resolve 或者 reject

// 0.5秒后返回input*input的计算结果:
function multiply(input) {
    return new Promise(function (resolve, reject) {
        console.log('calculating ' + input + ' x ' + input + '...');
        setTimeout(resolve, 500, input * input);
    });
}

// 0.5秒后返回input+input的计算结果:
function add(input) {
    return new Promise(function (resolve, reject) {
        console.log('calculating ' + input + ' + ' + input + '...');
        setTimeout(resolve, 500, input + input);
    });
}

var p = new Promise(function (resolve, reject) {
    console.log('start new Promise...');
    resolve(123);
});

p.then(multiply)
 .then(add)
 .then(multiply)
 .then(add)
 .then(function (result) {
    console.log('Got value: ' + result);
});

数组比较

Javascript怎么比较两个数组是否相同?
JS怎么比较两个数组是否有完全相同的元素?
Javascript不能直接用==或者===来判断两个数组是否相等,无论是相等还是全等都不行,以下两行JS代码都会返回false



<script type="text/javascript">
        alert([]==[]);
        alert([]===[]);
</script>

因为JavaScript里面Array是对象

要判断JS中的两个数组是否相同,需要先将数组转换为字符串,再作比较。以下两行代码将返回true

<script type="text/javascript">
        alert([].toString()== [].toString());
        alert([].toString()===[].toString());
</script>

JS要比较两个数组是否有相同的元素,即两个数组所有元素都相同,但元素的顺序不一定一致。只就需要先将数组进行排序,再比较两个数组是否相等。
试比较以下两行代码:

<script type="text/javascript">
        alert([1,2,3].toString()== [3,2,1].toString());
        alert([1,2,3].sort().toString()== [3,2,1].sort().toString());
</script>

有人说还有方法:连接两个数组,用hash判断重复?不知道其意思
对象数组不可以sort
改进算法:可以比较对象数组,但是顺序必须一致,不一致算作不相等
缺陷:比较数组的时候必须按顺序相等,因为数级里的 object 没法排序

完全可以解决对象里面的值类型不能也不算相等

<script>
const compare = (() => {
    function compareArray(a, b) {
        console.log("array", a, b);
        if (a.length !== b.length) {
            return false;
        }
        const length = a.length;
        for (let i = 0; i < length; i++) {
            if (!compare(a[i], b[i])) {
                return false;
            }
        }

        return true;
    }

    function compareObject(a, b) {
        console.log("object", a, b);
        const keya = Object.keys(a);
        const keyb = Object.keys(b);

        if (keya.length !== keyb.length) {
            return false;
        }

        return keya.every(key => {
            if (!compare(a[key], b[key])) {
                return false;
            }
            return true;
        });
    }

    function compare(a, b) {
        if (a === b) {
            return true;
        }

        if (typeof a !== typeof b || a === null || b === null) {
            return false;
        }

        if (Array.isArray(a)) {
            if (!Array.isArray(b)) {
                return false;
            }
            return compareArray(a, b);
        }

        if (typeof a === "object") {
            return compareObject(a, b);
        }

        console.log("value", a, b);
        return false;
    }

    return compare;
})();


var aa = [{ Name: "YuanXP", Id: 9 }, { Name: "YuanX", Id: 9 }];
var bb = [{ Name: "YuanXP", Id: 9 }, { Id: 9, Name: "YuanX" }];
var cc = [{ Name: "YuanXP", Id: 19 }, { Id: 9, Name: "YuanX" }];

var dd=[1,2,3]
var ff=["1",2,3]
var gg=[3,2,1]
console.log(compare(aa, bb));
console.log(compare(aa, cc));
console.log(compare(dd, ff));
console.log(compare(dd, gg));


</script>

当两个数组的元素顺序相同且元素都可以转换成字符串的情况下确实可行,但是这样的代码存有隐患,比如数字被转换成字符串,数字“1”和字符串“1”会被认为相等,可能造成调试困难,不推荐使用。

比较数组

// Warn if overriding existing method
if(Array.prototype.equals)
    console.warn("Overriding existing Array.prototype.equals. Possible causes: New API defines the method, there's a framework conflict or you've got double inclusions in your code.");
// attach the .equals method to Array's prototype to call it on any array
Array.prototype.equals = function (array) {
    // if the other array is a falsy value, return
    if (!array)
        return false;

    // compare lengths - can save a lot of time 
    if (this.length != array.length)
        return false;

    for (var i = 0, l = this.length; i < l; i++) {
        // Check if we have nested arrays
        if (this[i] instanceof Array && array[i] instanceof Array) {
            // recurse into the nested arrays
            if (!this[i].equals(array[i]))
                return false;       
        }           
        else if (this[i] != array[i]) { 
            // Warning - two different object instances will never be equal: {x:20} != {x:20}
            return false;   
        }           
    }       
    return true;
}
// Hide method from for-in loops
Object.defineProperty(Array.prototype, "equals", {enumerable: false});

大神还顺手给了比较Object的方法:

Object.prototype.equals = function(object2) {
    //For the first loop, we only check for types
    for (propName in this) {
        //Check for inherited methods and properties - like .equals itself
        //https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty
        //Return false if the return value is different
        if (this.hasOwnProperty(propName) != object2.hasOwnProperty(propName)) {
            return false;
        }
        //Check instance type
        else if (typeof this[propName] != typeof object2[propName]) {
            //Different types => not equal
            return false;
        }
    }
    //Now a deeper check using other objects property names
    for(propName in object2) {
        //We must check instances anyway, there may be a property that only exists in object2
            //I wonder, if remembering the checked values from the first loop would be faster or not 
        if (this.hasOwnProperty(propName) != object2.hasOwnProperty(propName)) {
            return false;
        }
        else if (typeof this[propName] != typeof object2[propName]) {
            return false;
        }
        //If the property is inherited, do not check any more (it must be equa if both objects inherit it)
        if(!this.hasOwnProperty(propName))
          continue;

        //Now the detail check and recursion

        //This returns the script back to the array comparing
        /**REQUIRES Array.equals**/
        if (this[propName] instanceof Array && object2[propName] instanceof Array) {
                   // recurse into the nested arrays
           if (!this[propName].equals(object2[propName]))
                        return false;
        }
        else if (this[propName] instanceof Object && object2[propName] instanceof Object) {
                   // recurse into another objects
                   //console.log("Recursing to compare ", this[propName],"with",object2[propName], " both named \""+propName+"\"");
           if (!this[propName].equals(object2[propName]))
                        return false;
        }
        //Normal value comparison for strings and numbers
        else if(this[propName] != object2[propName]) {
           return false;
        }
    }
    //If everything passed, let's say YES
    return true;
}
let a1=[1,2,3];
let b1=[3,2,"1"];
let a2=[{p:1,o:0}];
let b2=[{p:1,o:0}];
console.log(a1.sort().toString()==b1.sort().toString());
console.log(a1.sort())
console.log(b1.sort())
let c1={o:0,p:1};
let c2={p:1,o:0};

console.log(c1.equals(c2))