js笔记(暑假6)

         解决3:Object.prototype.toString.call({})          //正常是call传进去this,然后改变this指向,在这里传进去[],那么[]数组就代表this 返回结果为"[object Array]"
                     Object.prototype.toString.call([])          //这个返回是"[object Object]"
                     Object.prototype.toString.call(13)        //这个返回是"[object Number]"

67.this(在视频中this笔试真题讲解的部分,这两节主要是讲例题,此处例题在另一个文档中)
1.函数预编译过程中this指的是1window
例1:
    function test(c){                                //正常不经过new,this指的就是window,当对test进行new的话,test内部就会发生变化,本来AO中this指的是window,但是要是经过new之后,this就指的就是 Object.create(test.prototype)
        //var this = Object.create(test.prototype);         这是最精准的写法,下面的三行实现的是和这行一样的功能,但是这个比较精准
        /* var this = {
            __proto__ : test.prototype,
        };*/
        var a = 10;
        function b (){

        }
    }
    var AO = {
        arguments : [1],                         //其次还会生成以下两行,
        this : window,
        c : 1,                                           //首先我们了解的,AO中会生成以下三行。
        a : 1,
        b : function b(){

        }
    }
    test(1);
    new test ();                                   
2.全局作用域里this指的是window,也就是直接打印console.log(this) 是window
3.call/apply可以改变函数运行时this指向。
4.谁调用这个方法,这个方法里的this指的就是谁
假如这个方法在全局范围内执行,里面的this指的是window,因为没人调用它,进行空执行,走预编译,然后指的就是window
也就是obj.func(); func里面的this指的是obj

this笔试真题讲解
例1:最终结果为1,2,3,4,5
    function foo(){
        bar.apply(null,arguments);       //这个是将arguments作为参数传给了bar里面去,所以bar里有实参是一个数组,
    }
    function bar(){
        console.log(arguments);         //传进来的实参被传进arguments中去了,然后打印就是1,2,3,4,5
    }
    foo(1,2,3,4,5);
例2:this指向问题
    var name = "222";
    var a = {
        name : "111",
        say : function (){
            console.log(this.name);
        }
    }
    var fun = a.say;        //这个a.say只是一个函数引用,就相当于将a中的function拿出来了,函数是在外面执行的,这时this指的是window中的name
    fun();
    a.say();                //这个不用说,a调用say(),this肯定指向a。

    var b = {
        name : "333",
        say : function (fun){
            fun();
        }
    }
    b.say(a.say);            /* b.say()执行时,这时的this的确指的是b,但是里面参传进去的参数a.say是个函数引用,这个函数引用被谁也没调用所以执行时走的是预编译环节,this指的是window和b无关,要是把对象b中fun()改为this.fun(),那结果就是333了      */
    b.say = a.say;           /*将a.say这个函数赋给b*/
    b.say();                /*这个就是b自己调用say并执行,所以this指向b*/
最后一个可以这样理解:
    var a = 100;
    var deng = {
        a : 200,
        say : function (){
            console.log(a);               //打印a肯定是100,要是打印this.a那就是200
        }
    }
同理:
    function test (){
        console.log(this);
    }
    var test1 = {
        say : function (){
            test();                        //打印的也是window,自己一个人执行,谁也没调用。
        }
    }

68.arguments(caller不是arguments上面的属性,arguments属性只有callee和length)
1.一共就一个用法,arguments.callee指向函数自身引用。在哪个函数里面就指向哪个函数。
例1:
    function test(){
        console.log(arguments.callee);         //等价于test
    }
    test();
例2:利用立即执行函数实现阶乘运算,因为立即执行函数执行后会被立即销毁,所以就利用到了arguments.callee实现多次调用。
    var num = (function (n){
        if(n == 1){
            return 1;
        }
        return n * arguments.callee(n - 1);
    }(10))
2.func.caller中的caller是函数自己的属性,指向函数被调用的那个环境(也就是代指谁调用它的)
例1:
    function test(){
         demo();                                             //在test内部被调用执行,所以打印demo.caller结果就是test这个函数。
    }
    function demo(){
        console.log(demo.caller);
    }
    test();
视频此处开始讲题即this笔试真题下的19分钟开始。题以及答案见另一个文档。
知识点补充:未声明就使用变量报错,放在typeof中不报错。

69.克隆
1.浅层克隆:原始值克隆,只拷值。(克隆后target对象属性改变,对自己没影响)
例1:
    var liu = {
        name : 'LFY',
        age : 21,
    }
    function clone(origin , target){
        var target = target || {};                            //如果自己有原材料那就将原材料传进去进行克隆,如果没有原材料,那就target = {} 然后在进行克隆,将target对象返回
        for(var prop in liu){
            target[prop] = origin[prop];
        }
        return target;
    }
    var obj = clone(liu);
例2:当属性值为数组时,我将car进行改变 obj.car.push('LFY'); 然后访问liu.car的值也改变了。
    var liu = {
        name : 'LFY',
        age : 21,
        car :['visa' , 'unionpay'],
    }
    function clone(origin , target){
        var target = target || {};
        for(var prop in liu){
            target[prop] = origin[prop];
        }
        return target;
    }
    var obj = clone(liu);
2.深层克隆:
(1)判断是不是原始值
(2)判断数组还是对象(数组也能for in 因为数组也算特殊类型的对象,prop代表索引位)
(3)建立相应数组或对象
(4)将引用值重新当作一个对象再次进行拷贝,循环往复1234
例1:
    var obj = {
        name : "abd",
        age : 123,
        card : ['visa' , 'master'],
        wife : {
            name :'bcd',
            son : {
                name : 'abcds',
            }
        }
    }
    var obj1 = {};
    function deepClone(origin , target){
        var target = target || {};                                                                         //传进去原材料(target)时,用自己的,没有对象时,用工厂原材料(也就是新建的空对象)完成克隆。
        var toStr = Object.prototype.toString;
        var arrStr = "[object Array]"
        for(var prop in origin){
            if(origin.hasOwnProperty(prop)){
                if(origin[prop] !== "null" && typeof(origin[prop]) == 'object' ){  //判断是不是引用类型(值既不是null又是Object类型)
                    target[prop] = toStr.call(origin[prop]) == arrStr ? [] :{};             //引用类型再具体判断  是数组还是对象(target[prop] = toStr.call(origin[prop]) == arrStr ? [] :{};这个语句可以改为if else,但是这个语句更加简便)
                    /*if(toStr.call(origin[prop]) == arrStr){                                        //以下六行等价于上面那行,用三目运算符比较简洁。         
                        target[prop] = [];
                    }
                    else{
                        target[prop] = {};
                    }*/
                    deepClone(origin[prop] , target[prop]);                                    //将引用值作为对象再次进行拷贝
                }
                else {                                                                                              //当值为原始值时就是这个函数的出口
                    target[prop] = origin[prop];
                }
            }
        }
        return target;                                                                                        //当没有对象传进来时,就将一个空对象进行克隆,返回
    }
3.三目运算符:其实实质上就是if else,但是有个比if else强大的就是会有返回值,相当于在if else中加了个return。
(1)格式:条件判断?是:否
例1:    var num = 1 > 0 ? 2 + 2 : 1 + 1;                      //num=4;
例2:    var num = 1 > 0 ?("10" > "9" ? 1 : 0) : 2;         //括号中"10"和"9"比较的是ASCII码,"10"是两位字符串写,先1和9的ASCII码进行比较,"1"小于"9"。

猜你喜欢

转载自blog.csdn.net/LFY836126/article/details/81610009