JS之对象及其实例和静态函数

JS中对象是引用类型,引用类型的实例都需要通过new来实现。所以先要了解new操作符到底发生了什么。

new操作符

首先需要知道的是,在js的函数中,如果没有return值,那么默认返回undefined。

1
2
3
4
function Cat(name){
console.log(this)
}
new Cat('kele')

如果不给this添加属性,那么返回的将是一个空对象。

1
2
3
4
function Cat(name){
this.name=name
}
console.log(new Cat('kele'))//Cat {name:"kele"}

这样才能实现赋值👆

再来看new

1
var cat=new Cat()

这句代码从表面理解就是创建了一个Cat实例,然后赋值给cat变量,cat就会包含Cat构造函数中的方法和属性,new其实做了三件事

1
2
3
var cat={}//创建一个空的对象
cat.__proto__==Cat.prototype//将cat对象的proto属性指向构造函数的prototype
Cat.call(cat)//将Cat构造函数中方法指向cat变量

实例的隐式原型proto,均指向构造其本身的构造函数的显式原型prototype。所以cat变量才会是Cat的一个实例

下面来实现一个自定义new函数👇

1
2
3
4
5
6
7
8
9
10
11
function myNew(fn,...args){//fn为构造函数,arg为需要赋值的参数
var obj={}
obj.__proto__=fn.prototype//实现继承
var res=fn.apply(obj,args)//改变this指向
return typeof res==='Object'?res:obj//返回对象
}
//测试
function Cat(name){
this.name=name
}
console.log(myNew(Cat,'kele'))//Object { name: "kele" }

需要注意的是proto属性一定要指向构造函数的原型,避免不能继承原型上的方法。

实例函数

实例函数是指,函数的调用是基于Object类型的实例的。

1
var obj=new Object()
  • hasOwnProperty(name)

    判断对象自身是否拥有指定名称的实例属性,不会去检查原型链上的属性

  • propertyIsEnumerable(name)

    判断属性是否为实例属性并是否可枚举,如果是原型链上的属性或不可枚举将返回false

静态函数

指函数的调用基于Object类型本身而不需要通过类型的实例。

  • Object.create()

    创建并返回一个指定原型和属性的对象

  • Object.defineProperties()

    添加或修改对象的属性。

  • Object.getOwnPropertyNames()

    获取对象的所有实例属性和函数,不包含原型链继承的属性和函数,返回数组

  • Object.keys

    获取对象可枚举的实例属性,不包含原型链继承的属性,返回数组

查看评论