18.JavaScript学习笔记——this,callee,caller,克隆,三目运算符

this callee caller 克隆 三目运算符

1. this

  1. 函数预编译过程 this --> window
  2. 全局作用域中 this --> window
  3. call/apply可以在函数运行时改变this指向
  4. obj.func() func()里面的this指向obj 谁调用就指向谁
var name = "222";
var a = {
    name : "111",
    say : function () {
        console.log(this.name);
    }
};
var fun = a.say;
fun();    //222
a.say();  //111

var b = {
    name : "333",
    say : function (fun) {
        fun();
    }
};
b.say(a.say);   //222
b.say = a.say;
b.say();        //333
var foo = 123;
function print() {
    this.foo = 234;
    console.log(foo);  //234  这里打印的时window里面的foo,this指向window
}
print();
var foo = 123;
function print() {
    this.foo = 234;
    console.log(foo);  //123 这里打印的时window里面的foo,this指向print,若要打印234应该console.log(print.foo);
}
new print();

2. arguments.callee

arguments 的主要用途是保存函数参数, 但这个对象还有一个名叫 callee 的属性,返回正被执行的 Function 对象,也就是所指定的 Function 对象的正文。

function test() {
    console.log(arguments.callee == test);  //ture
}
test();

这有利于匿名函数的递归或者保证函数的封装性。

例如在立即执行函数使用递归时,由于没有函数名,所以需要借用arguments.callee来充当函数名。

var num = (function(n) {
    if(n == 1) {
        return 1;
    }
    return n * arguments.callee(n - 1);  //100!
}(100));

3. func.caller

caller返回一个函数的引用,这个函数调用了当前的函数; callee放回正在执行的函数本身的引用,它是arguments的一个属性。

function test () {
    demo();
}

function demo () {
    console.log(demo.caller);  //f test () {...}

    //test调用了demo函数,所以demo.caller返回test
}

callee是arguments对象的一个属性,指向 arguments 对象的函数,即当前函数。
caller是函数对象的一个属性,指向调用当前函数的函数体引用。

4. 克隆

4.1 浅层克隆

var obj = {
    name : 'abc',
    age : 123,
    sex : 'female'
}

var obj1 = {};

function clone(origin, target) {
    var target = target || {};  //提高容错
    for(var prop in origin) {
        target[prop] = origin[prop];
    }
    return target;
}

clone(obj, obj1);

上例中,克隆的对象都是基本类型,直接赋值就能实现克隆功能,且克隆后,target的值发生改变不会影响origin的值。

由于引用值的赋值,赋值的是地址,target和origin指向同一个内存,所以target改变,origin也会跟着改变。

4.2 深度克隆

var obj = {
        name : 'abc',
        age : 123,
        card : ['visa', 'master'],
        wife : {
            name : 'bcd',
            son : {
                name : 'aaa'
            }
        }
    };
var obj1 = {};

function deepClone(origin, target){
    var target = target || {},
        toStr = Object.prototype.toString,
        arrStr = '[object Array]';
    for(var prop in origin) {
        if(origin.hasOwnProperty(prop)) {
            if(origin[prop] !== 'null' && typeof(origin[prop]) == 'object') {
                if(toStr.call(origin[prop]) == arrStr) {
                    target[prop] = [];
                }else{
                    target[prop] = {};
                }
                deepClone(origin[prop], target[prop]);
            }else{
                target[prop] = origin[prop];
            }
        }
    }

    return target;
}

deepclone(obj, obj1);
  1. 遍历对象 for(var prop in obj)
  2. 判断是不是原始值 typeof() ‘object’
  3. 判断是数组还是对象 instanceof toString constructor
  4. 建立相应的数组或对象
  5. 递归

5. 三目运算符

三目运算符,也叫三元运算符。

基本语法:

expression ? santence1 : santence2;

条件判断expression是否为真,为真执行santence1,为假执行santence2,并返回值。

例如

var num = 1 > 0 ? 2 + 2 : 1 + 1;  //num = 4;

三目运算符像是一个简化版的if语句,但是与if不同的是,三目运算符会return返回值。

var num = 1 > 0 ? ("10" > 9 ? 1 : 0) : 2;

上例先运算括号内的语句;

"10" > 9是true,因此返回1;

这样就相当于var num = 1 > 0 ? 1 : 2;,所以num为1。

但是需要注意的是,"10" > "9"是false,字符串和数字比较大小会将字符串转化为数字再比较,而字符串和字符串之间的比较是逐位比较ascii码的大小。

运用三目运算符可以简化一些代码的编写,例如深度克隆中

var obj = {
        name : 'abc',
        age : 123,
        card : ['visa', 'master'],
        wife : {
            name : 'bcd',
            son : {
                name : 'aaa'
            }
        }
    };
var obj1 = {};

function deepClone(origin, target){
    var target = target || {},
        toStr = Object.prototype.toString,
        arrStr = '[object Array]';
    for(var prop in origin) {
        if(origin.hasOwnProperty(prop)) {
            if(origin[prop] !== 'null' && typeof(origin[prop]) == 'object') {
                // if(toStr.call(origin[prop]) == arrStr) {
                //     target[prop] = [];
                // }else{
                //     target[prop] = {};
                // }
                target[prop] = (toStr.call(origin[prop]) == arrStr) ? [] : {};//这里可以使用三目运算符代替上面的if...else
                deepClone(origin[prop], target[prop]);
            }else{
                target[prop] = origin[prop];
            }
        }
    }

    return target;
}

deepclone(obj, obj1);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值