在ES6之前,对象不是通过类创建的,而是用构造函数的特殊函数来定义。
创建对象可以通过以下三种方式:
构造函数是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋初始值,它总与new 一起使用。我们可以把对象中一些公共的属性和方法抽取出来,然后封装到一个函数里面。
普通函数
如果没有设置return,调用时则返回undefined
构造函数
不需要设置return,实例时默认返回该对象
构造函数通过原型定义的函数是所有实例对象共享的
JavaScript规定,每一个构造函数都有一个prototype属性,指向另一个对象,这个对象的所有方法和属性,都会被构造函数所拥有。
我们可以把相同的方法,直接定义在prototype对象上,这样所有实例对象就可以共享这些方法。
一般情况下,公橘雹拿共属性定义到构造函肆森数里面,而公共方法定义在原型对象上。
原型的主要作用是共享方法
创建对象时系统会自动添圆搭加一个 proto 属性指向我们构造函数的原型对象 prototype
对象原型(__proto __)和 构造函数原型对象(prototype)里面都有一个cunstructor属性,称为构造函数,因此它指向构造函数本身。
当Star.prototype 以对象的形式添加方法时,会删除constructor属性,所以需要我们手动添加回来
我在Object原型对象中定义个dacen方法,ldh实例对象也能访问到。Object是原型链的尽头
查找机制:
ldh实例首先会在自身对象中查找,如果找不到该方法,则会在Stat原型对象中找,如果还找不到,就会通过__ proto__原型,到Object原型对象上找,直到为null。
函数对象都是有Function函数生成的,而Function自身也是函数,则有Function.__ proto__ === Function.prototype // true (函数是自身的实例)
Object 也是构造函数,所以Object.__ proto__ === Function.prototype //对象是函数的实例
1、 Foo.getName()
为什么输出2,不是3?这就得说说构造函数的静态属性与实例属性。 我们都知道函数属于对象,而对象拥有可以自由添加属性的特性,函数也不例外,构造函数也是函数:
比如这个例子中,我为构造函数Fn添加了静态属性person与静态方法sayName,我们可以通过构造函数Fn直接访问。在JS中,我们将绑定在构造函数自高衡身上的属性方法称为静态成员,静态成员可通过构造函数自身访问,而实例无法访问。
那有什么属性是实例可以访问而构造函数自身无法访问的呢,当然有,比如实例属性。这里我将实例属性细分为构造器属性与原型属性两种,看下面的例子:
2、 getName()
这里考的是变量提升与函数声明提升 ,function getName()变量提升,声明后被 getName= function(){...}覆盖,输出4
3、 Foo().getName()
getName是全局变量,所以在函数Foo内也能直接访问,于是getName被修改成了输出1的函数,之后返回了一个this。
由于Foo().getName()等同于window.Foo().getName(),所以this指向window,这里返回的this其实就是window。
4、 getName()
这里输出1已经毫无悬念,上一分析中,getName的值在Foo执行时被修改了,所以再调用getName一样等同于window.getName(),同样是输出1。
5、 new Foo.getName()
等价于new (Foo.getName()),在分析一中我们已经知道了Foo.getName是Foo的静态方法,这里的getName虽然是Foo的静态方法,但是既没有继承Foo的原型,自身内部也没提供任何构造器属性(this.name这样的),所以new这戚知做个静态方法只能得到一个空属性的实例。
因此这里new的过程就相当于单纯把Foo.getName执行了一遍输出2,然后返回了一个空的实例
6、 new Foo().getName()
这里考了new基本概念,首先这个调用分为两步,第一步new Foo()得到一个实例,第二步调用实例的getName方法
7、 new new Foo().getName()
第一眼也是看的我很懵,我们知道new一个函数都是new fn(),函数带括号的。所以这里其实可以拆分成这样:
由于构造函数Foo自身啥构造器属性都没有,只有原型上有一个输出3的原型方法,所以实例a是一猛虚个原型上有输出3的函数getName。
那么第二步,由于原型上的getName方法也没提供构造器属性,自身原型上也没属性,所以第二步也算是单纯执行a.getName()输出3,然后得到了一个什么自定义属性都没有实例。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)