美文网首页程序员Web前端之路
JS中常见的几个问题及概念

JS中常见的几个问题及概念

作者: 楼心漫 | 来源:发表于2017-04-21 14:57 被阅读125次
    《我心中尚未崩坏的地方》

    写在前面

    此文作为笔记所用,且有的地方可能有点小错误什么的,欢迎大佬们指点或指正,小花在此谢过~

    1. JS中浅拷贝及深拷贝

    数组浅拷贝代码举例

    var arr = ["One","Two","Three"];
    
    var arrto = arr;
    arrto[1] = "test";
    document.wrirteln("数值的原始值:" + arr + "<br />");  //Export:数组的原始值:One,test,Three
    
    document.wrirteln("数值的原始值:" + arrto + "<br />");  //Export:数组的新值:One,test,Three
    
    • 解决数组浅拷贝的方法有:

      1. arr.slice(0) 得到的是一个新数组
      2. var arrtooo = arr.concat();
    • 对象的深拷贝(将对象中属性遍历一次得到一个新数组):

    方法一:

    var deepCopy = function(source){
        var result = {};
        
        for (var key in source){
            result[key] = typeof source[key] === 'object'?deepCopy(source[key]):source[key];
        }
        
        return result;
    }
    

    方法二:

    str = JSON.stringify(obj), //系列化对象
    newobj = JSON.parse(str); //还原
    
    将它封装成一个函数之后:
    function jsonClone(obj) {
        return JSON.parse(JSON.stringify(obj));
    }
    
    var clone = jsonClone(obj);
    

    2. 关于chrome无法访问XMLHttpRequest

    关于chrome无法访问XMLHttpRequest,原因是chrome 到安全性的问题,限制了本地跨域,可用的方式有,利用jQuery来改写,还有就是在chrome图标属性的目标项更改参数设置为"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" (此处有一个空格)--args --disable-web-security

    3. JSON的输出方式

    //此部分不重要,初学者可观看
    var data01 = {
            "total_page": 2,
            "cover_url_large": "xxx",
            "tracks": [{
                "id": 237730,
                "track_title": "张杰 - 无情的情书(live版)",
                "announcer": {
                    "nickname": "tiny121",
                },
                "duration": 310,
                "subordinated_album": {
                    "album_title": "tiny550_album 001",
                },
                "source": 2,
            },
                {
                    "track_title": "张杰 - 无情的情书(...)",
                    "announcer": {
                        "nickname": "dgfsgdfdhfgdsgfhdsgu",
                    },
                    "duration": 310,
                    "subordinated_album": {
                        "id": 86492,
                    },
                    "source": 2,
                }
            ]
        }
        document.write(data01.tracks[0].track_title);
        document.write(data01.tracks[0].announcer.nickname);
        document.write(data01.tracks[1].announcer.nickname);
        document.write(data01.tracks[1].track_title);
        
        //其中data01为json名,tracks为一个数组包含多个对象
    
    

    4. 自执行匿名函数(IIFE)

    • 常见格式:(function() { /* code */ })();
    • 解释:包围函数(function(){})的第一对括号向脚本返回未命名的函数,随后一对空括号立即执行返回的未命名函数,括号内为匿名函数的参数。
    • 作用:可以用它创建命名空间,只要把自己所有的代码都写在这个特殊的函数包装内,那么外部就不能访问,除非你允许(变量前加上window,这样该函数或变量就成为全局)。各JavaScript库的代码也基本是这种组织形式。
    • 最大的用途是创建闭包

    注意:函数声明后面不允许在后面直接使用小括号

    函数声明和函数表达式不同之处在于,一、Javascript引擎在解析javascript代码时会‘函数声明提升’(Function declaration Hoisting)当前执行环境(作用域)上的函数声明,而函数表达式必须等到Javascirtp引擎执行到它所在行时,才会从上而下一行一行地解析函 数表达式,二、函数表达式后面可以加括号立即调用该函数,函数声明不可以,只能以fnName()形式调用 。

    fnName();
    
    function fnName(){
        ...
    } //正常,因为‘提升’了函数说明,函数调用可在函数声明之前
    
    fnName();
    var fnName = function(){
        ...
    }//报错,变量fnName还未保存对函数的应用,函数调用必须在函数表达式之后
    
    var fnName = function(){
        alert('Hello World');
    }(); //函数表达式后面加括号,当JavaScript引擎解析到此处时能立即调用函数
    
    function fnName(){
        alert('Hello World');
    }(); //不会报错,但是JavaScript引擎只解析函数声明,忽略后面的括号,函数声明不会被调用
    
    function(){
        console.log('Hello World');
    }(); //语法错误,虽然匿名函数属于函数表达式,但是未进行赋值操作,
    //所以JavaScript引擎开头的function关键字当做函数声明,报错:需要一个函数名
    

    javascript中没用私有作用域的概念,如果在多人开发的项目上,你在全局或局部作用域中声明了一些变量,可能会被其他人不小心用同名的变量给覆盖 掉,根据javascript函数作用域链的特性,可以使用这种技术可以模仿一个私有作用域,用匿名函数作为一个“容器”,“容器”内部可以访问外部的变 量,而外部环境不能访问“容器”内部的变量,所以( function(){…} )()内部定义的变量不会和外部的变量发生冲突,俗称“匿名包裹器”或“命名空间”。

    5.dataset 自定义属性

    • 这里的data-前缀就被称为data属性,其可以通过脚本进行定义,也可以应用CSS属性选择器进行样式设置。数量不受限制,在控制和渲染数据的时候提供了非常强大的控制。
    var expenseday2 = document.getElementById('day2-meal-expense');  
    var typeOfDrink = expenseday2.dataset.drink;
    
    • 删除data属性:delete expenseday2.dataset.meal;
    • 添加data属性:expenseday2.dataset.dessert = 'icecream';
    • data在css中的使用: .mm[data-name='张含韵']{ }

    6. 迭代器模式

    提供一种方法顺序一个聚合对象中各个元素,而又不暴露该对象内部表示。

    • 访问一个聚合对象的内容而无需暴露它的内部表示。
    • 访问一个聚合对象的内容而无需暴露它的内部表示。
    • 遍历的同时更改迭代器所在的集合结构可能会导致问题

    7. map()和filter()

    • filter是满足条件的留下,是对原数组的过滤;filter 是根据返回的值是否为真来判断是否保留元素
    • map则是对原数组的加工,映射成一一映射的新数组
    function pp(x){return x % 2;}
    function px(x){return x % 2;}
    var m = xx.map(pp);
    var f = xx.filter(px);
    
    • array.map(callback[, thisObject]);

    callback : 从当前的元素函数产生新的数组的元素。
    thisObject : 对象作为该执行回调时使用

    8. 闭包

    闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。

    • 由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。(解决方法是,在退出函数之前,将不使用的局部变量全部删除)
    • 闭包会在父函数外部,改变父函数内部变量的值。

    9. ES5中的bind()方法

    bind和call以及apply一样,都是可以改变上下文的this指向的。不同的是,call和apply一样,直接引用在方法上,而bind绑定this后返回一个方法,但内部核心还是apply。

    相关文章

      网友评论

        本文标题:JS中常见的几个问题及概念

        本文链接:https://www.haomeiwen.com/subject/ytpdzttx.html