JavaScript中prototype和proto的使用

每个函数都有一个prototype属性,这个属性是指向一个对象的引用,这个对象成为原型对象,原型对象包括函数实例共享的方法和属性,也就是说将函数用作构造函数调用(使用new操作符调用)的时候,新创建的对象会从原型对象上继承属性和方法。

function Obj(){
	this.a=[];//实例变量
	this.fn=function(){};//实例方法
}


私有变量、函数

在函数内定义的变量和函数如果不对外提供接口,那么外部无法访问到,也就变成私有变量和私有函数。

function Obj(){
  var a=0;//私有变量
  var fn=function(){};//私有函数
}
var o=new Obj();
console.log(o.a);//undefined
console.log(o.fn);//undefined


静态变量、函数

当定义一个函数后,通过“.”为其添加的属性和函数,通过对象本身任然可以访问得到,但是其实例却访问不到,这样的变量和函数分别被称为静态变量和静态函数。

function Obj(){
	this.a=[];//实例变量
	this.fn=function(){};//实例方法
}
var obj1=new Obj();
obj1.a.push(1);
obj1.fn={};
console.log(obj1.a);//[1]
console.log(typeof obj1.fn);//object

var obj2=new Obj();
console.log(obj2.a);//[]
console.log(typeof obj2.fn);//function,并没有和obj1的fn共享
obj1中修改了a和fn,但是在obj2中没有改变,由于数组和函数都是对象,是引用类型,这就说明obj1中的属性和方法与obj2中的属性与方法 虽然同名但是却不是同一个引用,而是对Obj对象定义的属性和方法的 复制


prototype

主要创建一个新函数,就会根据一组特定的规则为该函数创建一个prototype属性,默认情况下prototype属性会默认获得一个constructor(构造函数)属性,这个属性是一个指向prototype属性所在函数的指针。

当调用构造函数创建一个实例的时候,实例内部将包含一个内部指针(很多浏览器这个指针名字为__proto__)指向构造函数的prototype,这个连接存在于实例和构造函数的prototype之间,而不是实例与构造函数之间。

function Person(name){
	this.name=name;
}
Person.prototype.printName=function(){
	alert(this.name);
}
var p1=new Person('John');
var p2=new Person('Bob');
Person的实例p1中包含了name属性,同时自动生成一个__proto__属性,该属性指向Person的prototype,可以访问到prototype内定义的printName方法。

写一段程序测试一下看看prototype内属性和方法是能够共享

function Person(name){
	this.name=name;
}
Person.prototype.printName=function(){
	alert(this.name);
}
Person.prototype.share=[];
var p1=new Person('John');
var p2=new Person('Bob');
p1.share.push(1);
p2.share.push(2);
console.log(p2.share);//[1,2]
假如不用prototype为Person添加方法

Person.say=function(){
	alert('asda')
}
p1.say();//Uncaught TypeError: p1.say is not a function

以下三点需要谨记:

1. 每个对象都具有一个名为__proto__属性;

2. 每个构造函数(构造函数标准为大写开头,如Function(),Object()等等JS中自带的构造函数,以及自己创建的)都具有一个prototype的方法(注意:既然是方法,那么就是一个对象(JS中函数同样是对象),所以prototype同样带有__proto__属性);

3. 每个对象的__proto__属性指向自身构造函数的prototype;

console.log(p1.__proto__===Person.prototype);//true
//p1的__proto__指向其构造函数Person的prototype
console.log(Person.__proto__===Function.prototype);//true
//Fun的__proto__指向其构造函数Function的prototype
console.log(Function.__proto__===Function.prototype);//true
//Function的__proto__指向其构造函数Function的prototype
console.log(Function.prototype.__proto__===Object.prototype);//true
//Function.prototype的__proto__指向其构造函数Object的prototype
//Function.prototype是一个对象,同样是一个方法,方法是函数,所以它必须有自己的构造函数也就是Object
console.log(Person.prototype.__proto__===Object.prototype);//true
//此处可以知道一点,所有构造函数的的prototype方法的__都指向__Object.prototype(除了....Object.prototype自身)
console.log(Object.__proto__===Function.prototype);//true
//Object作为一个构造函数(是一个函数对象!!函数对象!!),所以他的__proto__指向Function.prototype
console.log(Object.prototype.__proto__===null) ;//true
//Object.prototype作为一切的源头,他的__proto__是null

关于constructor

constructor在原型链中,是作为对象prototypr的一个属性存在的,它指向构造函数(由于主要讲原型链,这个就没在意)

var obj={};
console.log(obj.__proto__===Object.prototype);//true
console.log(obj.__proto__.__proto__===null);//true
console.log(obj.__proto__.constructor===Object);//true
console.log(obj.__proto__.constructor.__proto__===Function.prototype);//true
console.log(obj.__proto__.constructor.__proto__.__proto__===Object.prototype);//true
console.log(obj.__proto__.constructor.__proto__.__proto__.__proto__===null);//true
console.log(obj.__proto__.constructor.__proto__.__proto__.constructor.__proto__===Function.prototype);//true






  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值