js底层方法详解

如何判断方法的所属对象

hasOwnProperty:
console.log({}.hasOwnProperty);
//function hasOwnProperty() { [native code] }
console.log(Object.hasOwnProperty);
//function hasOwnProperty() { [native code] }

 console.log({}.defineProperties);
//undefined
 console.log(Object.defineProperties);
// function defineProperties() { [native code] 

可以分别用实例和构造器调用方法

  • 若方法在实例上,则此方法必定在构造器上
  • 若方法在构造器上,此方法不一定在原型上

控制台打印的方法有的是灰色的?

1. 直接将属性定义在{}中:

这里写图片描述

可见自定义属性key1是深色中,而指向原型对象的对象proto是灰色的;

2. 用Object.defineProperty()定义属性

这里写图片描述

此时看到key1是亮色,而自定义的key2也是灰色,why?

这里写图片描述

打印出key1,key2两个属性的的描述器后发现:

  • {}定义的属性的描述中,writable、enumerable、configurable都是true
  • Object.defineProperty定义的属性中描述全为false

这里写图片描述

上图中,将enumerable属性改为true后,发现其属性值变深色了。

说明:不可枚举的属性值为浅色,即不会出现在for in中

这里写图片描述

如何判断对象是否包含某属性

用obj.key
var obj = {key:undefined};
console.log(obj.key);//undefined
console.log(obj.noname);//undefined

然而key是obj的属性,因此上面方法不可行

用Object.hasOwnProperty
var obj = {key:undefined};
console.log(Object.hasOwnProperty(obj,key));//true
console.log(Object.hasOwnProperty(obj,noname));//false

然而当hasOwnProperty方法被重写时就要注意了:

var obj = {
    hasOwnProperty:function(){
        return false;
    },
    hello:123
};
obj.hasOwnProperty('hello');//false

应该使用:

({}).hasOwnProperty.call(obj,'hello');//true

某些方法两边有私有属性的标志,如__proto__

这些方法作者的本意不想让用户调用,但是js中所有方法都是可以调用的,那么肯定有其他更好的方法来调用这些私有方法

例如obj.__defineGetter__,此方法不推荐直接使用:

obj.__defineGetter__('key1',function(){return 'value1'});
console.log(obj.key1)//'value1'

可以使用以下两个标准方法替代
1.

var obj = {get key1(){return 1},get key2(){return 2}}

2.

Object.defineProperty(obj,"value1",{
    get:function(){return 1;}
})

数组length属性

var arr = [1,2,3];
arr.length = 6;
console.log(arr);//[1,2,3,undefined*3]
5 in arr;   //false
arr[5] = undefined;
5 in arr;   //true

undefined定义不会被覆盖

因为全局undefined只是保存了undefined实际类型的副本

setTimeout中this指向全局

function Foo() {
    this.value = 42;
    this.method = function() {
        // this 指向全局对象
        console.log(this.value); // 输出:undefined
    };
    setTimeout(this.method, 500);
}
new Foo();

setInterval方法优化

function foo(){
    // 阻塞执行 1 秒
}
setInterval(foo, 100);

此时会有10个待执行的foo堆积下来,因此可在setInterval内部使用setTimeout:

function foo(){
    // 阻塞执行 1 秒
    setTimeout(foo, 100);
}
foo();

隐藏使用的eval函数

由于setTimeout中第一个参数若为function,则其内this指向全局,而第一个参数若为字符串,则相当于隐式的eval:

function foo() {
    // 将会被调用
}

function bar() {
    function foo() {
        // 不会被调用
    }
    setTimeout('foo()', 1000);
}
bar()
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值