javascript部分

JS的执行机制
特点:
        1、单线程,
            即,同一个时间只能做一件事,不要多线程是为了提升效率 (用途是与用户互动,操作Dom,否则会带来很复杂的同步问题)
        2、任务队列(消息队列),
            同步任务(主线程上排队执行),异步任务(不进入主线程,而是进入‘任务队列task queue’,只有任务队列通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行)
            console.log('a');
            while(true){}
            console.log('b')
            //只能输出a,因为是同步任务,程序由上到下执行,遇到while死循环,下面的语句就没法执行
            console.log('a');
            setTimeout(function(){
                console.log('b')
            },0)
            while(true){}
            //还是只能输出a,setTimeout()就是个异步任务。在所有同步任务执行完之前,任何的异步任务是不会执行的
        3、Event Loop
            1)所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
            2)主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
            3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
            4)主线程不断重复上面的第三步。
            
    主线程从"任务队列"中读取事件,这个过程是循环不断的,所以整个的这种运行机制又称为Event Loop(事件循环)。只要主线程空了,就会去读取"任务队列",这就是JavaScript的运行机制。
        
    哪些语句会放入异步任务队列及放入时机
        1、setTimeout和setlnterval
        2、DOM事件
        3、ES6中的Promise
        4、Ajax异步请求
    javascript 代码运行分两个阶段:    
        1、预解析 ---把所有的函数定义提前,所有的变量声明提前,变量的赋值不提前
        2、执行 ---从上到下执行(按照js运行机制)
            for(var i=0;i<5;i++){
                setTimeout(function(){
                    console.log(i)
                },1000)
            }
            //5个5     在到达指定时间时,定时器就会将相应回调函数插入“任务队列”尾部。这就是“定时器(timer)”功能
    关于定时器的重要补充:
        1、定时器包括setTimeout与 setInterval 两个方法。它们的第二个参数是指定其回调函数推迟/每隔多少毫秒数后执行。
        2、对于第二个参数有以下需要注意的地方:当第二个参数缺省时,默认为 0;
            当指定的值小于 4 毫秒,则增加到 4ms(4ms 是 HTML5 标准指定的,对于 2010 年及之前的浏览器则是 10ms);也就是说至少需要4毫秒,该setTimeout()拿到任务队列中。
2、js的浅copy和深copy
JS浅copy与深copy //后台返回了一堆数据,你需要对这堆数据做操作,多人开发情况下,没办法明确这堆数据是否有其它功能也需要使用,直接修改可能会造成隐性问题,深拷贝能帮你更安全安心的去操作数据,
        1、封装一个深拷贝的函数(PS:只是一个基本实现的展示,并非最佳实践)
            function deepClone(obj){//递归
                let objClone = Array.isArray(obj)?[]:{};
                if(obj && typeof obj==="object"){
                    for(key in obj){
                        if(obj.hasOwnProperty(key)){
                            //判断ojb子元素是否为对象,如果是,递归复制
                            if(obj[key]&&typeof obj[key] ==="object"){
                                objClone[key] = deepClone(obj[key]);
                            }else{
                                //如果不是,简单复制
                                objClone[key] = obj[key];
                            }
                        }
                    }
                }
                return objClone;
            }    
            let a=[1,2,3,4],
                b=deepClone(a);
            a[0]=2;
            console.log(a,b);
        2、slice只能实现一维数组的深拷贝,,
            let a=[0,1,[2,3],4],
                    b=a.slice();
            a[0]=1;
            a[2][0]=1;
            console.log(a,b);
            //是做不到的
        3、concat方法
            与slice也存在这样的情况,他们都不是真正的深拷贝
        4、我们还可以借用JSON对象的parse和stringify
            function deepClone(obj){
                let _obj = JSON.stringify(obj),
                    objClone = JSON.parse(_obj);
                return objClone
            }    
            let a=[0,1,[2,3],4],
                b=deepClone(a);
            a[0]=1;
            a[2][0]=1;
            console.log(a,b);
        5、JQ的extend方法 //$.extend( [deep ], target, object1 [, objectN ] )
            let a=[0,1,[2,3],4],
                b=$.extend(true,[],a);
            a[0]=1;
            a[2][0]=1;
            console.log(a,b);

 3、js类型转换  

显示转换
                1、Number() 
                    1)如果是布尔值,true和false分别被转换为1和0
                    2)如果是数字值,返回本身。
                    3)如果是null,返回0.
                    4)如果是undefined,返回NaN。
                    5)如果是字符串,遵循以下规则:
                       1、如果字符串中只包含数字,则将其转换为十进制(忽略前导0)
                       2、如果字符串中包含有效的浮点格式,将其转换为浮点数值(忽略前导0)
                       3、如果是空字符串,将其转换为0
                       4、如果字符串中包含非以上格式,则将其转换为NaN
                    6)如果是对象,则调用对象的valueOf()方法,然后依据前面的规则转换返回的值。如果转换的结果是NaN,则调用对象的toString()方法,再次依照前面的规则转换返回的字符串值。
                2、parseInt(string, radix)
                    1)忽略字符串前面的空格,直至找到第一个非空字符
                    2)如果第一个字符不是数字符号或者负号,返回NaN
                    3)如果第一个字符是数字,则继续解析直至字符串解析完毕或者遇到一个非数字符号为止
                    4)如果上步解析的结果以0开头,则将其当作八进制来解析;如果以0x开头,则将其当作十六进制来解析
                    5)如果指定radix参数,则以radix为基数进行解析
                3、parseFloat(string)
                    它的规则与parseInt基本相同,但也有点区别:字符串中第一个小数点符号是有效的,另外parseFloat会忽略所有前导0,如果字符串包含一个可解析为整数的数,则返回整数值而不是浮点数值。
                4、toString(radix)
                    除 undefined 和 null 之外的所有类型的值都具有toString()方法,其作用是返回对象的字符串表示。
                5、String(mix)
                     1)如果有toString()方法,则调用该方法(不传递radix参数)并返回结果
                     2)如果是null,返回”null3)如果是undefined,返回”undefined”
                6、Boolean(mix)
                    以下值会被转换为false:false、”"、0、NaN、null、undefined,其余任何值都会被转换为true。
            隐式转换
                1、isNaN(mix)
                2、递增递减操作符(包括前置和后置)、一元正负符号操作符
                     1)如果是包含有效数字字符的字符串,先将其转换为数字值(转换规则同Number()),在执行加减1的操作,字符串变量变为数值变量。
                     2)如果是不包含有效数字字符的字符串,将变量的值设置为NaN,字符串变量变成数值变量。
                     3)如果是布尔值false,先将其转换为0再执行加减1的操作,布尔值变量编程数值变量。
                     4)如果是布尔值true,先将其转换为1再执行加减1的操作,布尔值变量变成数值变量。
                     5)如果是浮点数值,执行加减1的操作。
                     6)如果是对象,先调用对象的valueOf()方法,然后对该返回值应用前面的规则。如果结果是NaN,则调用toString()方法后再应用前面的规则。对象变量变成数值变量。
                3、加法运算操作符
                4、乘除、减号运算符、取模运算符
                5、逻辑操作符(!、&&、||)
                6、关系操作符(<, >, <=, >=)
                7、相等操作符(==)

 4、js的组成部分  

javascript是一种专为与网页交互而设计的脚本语言,由下列三个不同的部分组成:

    1、ECMAScript,由ECMA-262定义,提供核心语言功能;
    2、文档对象模型(DOM),提供访问和操作网页内容的方法和接口;
    3、浏览器对象模型(BOM),提供与浏览器交互的方法和接口;    

 5、js严格模式

"use strict"; //是进入严格模式的标志,放在脚本文件的第一行,则整个脚本都将以"严格模式"运行。如果这行语句不在第一行,则无效,整个脚本以"正常模式"运行
        1、全局变量显式声明
            变量必须先用var声明,然后再使用 
        2、静态绑定
            1)禁止使用with()语句
            2)创设eval作用域
        3、禁止this关键字指向全局对象
        4、禁止在函数内部遍历调用栈
        5、禁止删除变量
            严格模式下无法删除变量。只有configurable设置为true的对象属性,才能被删除。
            'use strict'
            var x;
            delete x; //语法错误
            var o = Object.create(null,{
                'x':{
                    value:1,
                    configurable:true
                }
            })
            delete o.x //删除成功
        6、严格模式下,对一个使用getter方法读取的属性进行赋值,会报错。
            var o = {};
            Object.defineProperty(o, "v", { value: 1, writable: false });
            o.v = 2;
            console.log(o)//1   虽然没有改变,但是也没有报错
            
       'use strict';
            var o = {};
            Object.defineProperty(o, "v", { value: 1, writable: false });
            o.v = 2; // 报错
            console.log(o)
        7、严格模式下,对禁止扩展的对象添加新属性,会报错。
            var o = {};
            Object.preventExtensions(o);
            o.v = 1;
            console.log(o)//空对象
            
       'use strict';
            var o = {};
            Object.preventExtensions(o);
            o.v = 1; //
            console.log(o)
        8、严格模式下,删除一个不可删除的属性,会报错。
            delete Object.prototype; //无影响
            
            'use strict';
            delete Object.prototype; // 报错
        9、对象不能有重名的属性
        10、函数不能有重名的参数
        11、禁止八进制表示法
        12、arguments对象的限制
        13、 函数必须声明在顶层
        14、保留字
原文地址:https://www.cnblogs.com/slightFly/p/10588933.html