JavaScript 面向对象(一)——原型

一、类,对象,函数

var obj = {};//对象
obj.num = 10;//js对象中成员的增加,可以通过直接赋值实现

console.log(obj);
console.log(window);

运行结果:
在这里插入图片描述
obj可以看做window的一个成员。

//fun是一个函数
var fun  = function () {};

//funObj是function的对象,运行结果证明它也是一个匿名函数
var funObj  = new Function;

//klass是fun的对象,所以fun既是函数又是类
var klass = new fun;

console.log(klass instanceof fun);
console.log(window);
//属性caller:是对fun的高级调用
//属性lenght:参数个数

运行结果:
在这里插入图片描述
所以javaScript中函数既是类也是对象

//一个函数也是类
function Klass() {
	this.num = 3;//类中写了一个成员
}
var obj = new Klass;//new一个对象
console.log(window);

运行结果:
在这里插入图片描述
运行结果中,类里没有num这个成员,而对象中有。
这是因为在var obj = new Klass; 时,实际上是申请了一段实例空间,将其首地址赋值给了对象obj。此时需要执行Klass的构造方法,而构造方法就是这个函数本身,( object.method)这个方法现在有前缀(obj),就相当于调用这个函数,谁调用,this就是谁。所以现在this指的是obj,obj有了num成员,并不是一开始就给Klass加好的成员。

二、prototype,proto

var Fun = function() {};
var fun = new Fun;

console.log(window);

运行结果:
在这里插入图片描述

可以看到prototype是object类型,属于Fun的一个成员,它其中有constructor,又指向了Fun本身。而fun中没有这个prototype。

var Fun = function() {};
var fun = new Fun;

console.log("fun.prototype:", fun.prototype);
console.log("Fun.prototype:", Fun.prototype);
console.log("fun.__proto__:", fun.__proto__);
console.log(window);

运行结果:
在这里插入图片描述
所以类有prototype属性(即原型对象),而对象没有
由上面运行结果可以看到和prototype__proto__两个一模一样。证明了对象有一个__proto__属性,不显示却存在(加下划线的就是不想让外部使用,尽量不要用),它是一个指针,指向类的prototype对象(对象其实就是一个指针,指向某个空间;prototype所指向的空间称为原型空间)。那么一个类的多个对象的__proto__均指向类的prototype成员,而prototype作为一个成员也一定有自己的隐含的__proto__。

var Fun = function() {};
var one = new Fun;
var two = new Fun;

//给类的原型对象增加成员
Fun.prototype.member = "这是一个新加的成员";
console.log("Fun.prototype.member", Fun.prototype.member);
one.member = "one更改了成员!";
two.member = "two更改了成员!";
//给one和two别增加了member成员,各自修改了自己成员的值

two.__proto__.member = "你变不变";
//更改了Fun的prototype的member

console.log("****************");
console.log("Fun.prototype.member", Fun.prototype.member);
console.log("Fun.member", Fun.member);
console.log("two", two);
console.log("one", one);

运行结果:
在这里插入图片描述
由结果可以得出member不是Fun的!原型类型的成员(就是prototype里的成员)通过类类型名称必须要加prototype(类类型.prototype.成员名称),否则JavaScript不会自动查找,也就无法使用。

三、JavaScript处理左值和右值

eg: a.b = c.d
a.b 为左值,JavaScript里的各种值实际上就是键值对,左值即空间,可以把值装入,也就是键值对中的键,在a中查找键b,若找到了就将右值赋给它,将原来的值覆盖;找不到则新增一个键(成员),将右值赋给它。
c.d在此时代表一个值,实际上右值也是空间,一个键,在c中查找d如果找到,将其中的值取出,使用;如果找不到就沿着__proto__去原型空间中查找,而prototype也有__proto__,如果找不到就继续顺着原型链去父类的原型空间查找,直到遍历全部的原型空间,均未查到,则该右值为undefined。

四、原型链

在这里插入图片描述

指导:mec
如有错误,请指正,谢谢。

猜你喜欢

转载自blog.csdn.net/A_BCDEF_/article/details/83447469