JavaScript prototype的深入理解

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

1.函数的作用域

function demo(){
    var a=0; //私有变量
    var privateFunc=function(){ //私有函数
    }
}
var mydemo = new demo(); //实例化demo函数
console.log(mydemo.a); //undefined
console.log(mydemo.privateFunc); //undefined

       在函数内定义的变量和函数如果不对外提供接口,那么外部将无法访问到,只能在demo函数内部使用,也就是变为私有变量和私有函数,demo的实例是没法访问的。

2.静态变量、静态函数

function demo(){
}
demo.a=0; //静态变量
demo.staticFunc = function(){ //静态函数
}

console.log(demo.a); //0
console.log(typeof demo.staticFunc); //function
var mydemo = new demo();
console.log(mydemo.a); //undefined
console.log(typeof mydemo.staticFunc); //undefined

       a.类的静态变量/函数通过[类名.类函数名称]赋值;

       b.调用时用[类名.类变量/函数名称()]直接调用;

       c.类的实例无法调用类的静态变量/函数。

3.实例化后可以访问的变量和方法

       通过this指针可以实现一些实例化之后可以访问的变量和函数,但是每实例化一个函数,就产生一个对原函数的属性和函数的复制,如下例,实例化之后的对象是可以访问一开始初始化的值的。但是每实例化一个会产生一个复制,互相不影响。这个对于函数来说有很大的问题,因为方法都是在做完全一样的功能,但是却又两份复制,如果一个函数对象有上千个实例方法, 那么它的每个实例都要保持一份上千个方法的复制,这显然是不科学的,因此,prototype应运而生。

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

console.log(typeof demo.a); //undefined
console.log(typeof demo.fn); //undefined

var mydemo1 = new demo();
console.log(typeof mydemo1.a); //object
console.log(typeof mydemo1.fn); //function

var mydemo2 = new demo();
mydemo2.a.push(1);
mydemo2.fun = {};

console.log(mydemo2.a); //[1]
console.log(typeof mydemo2.fn); //object
console.log(mydemo1.a); //[]
console.log(typeof mydemo1.fn); //function

 

4.prototype 

        在js中每创建一个函数就产生一个prototype函数,默认情况下,prototype会默认获得一个constructor函数,这个函数相当于一个指向原函数的指针。一旦创建了一个函数,相当于创建了一个对象,这个对象有prototype属性,prototype又包含constructor这个属性。

function Person(name){
    this.name=name;
}
Person.prototype.share=[];
Person.prototype.printName=function(){
    alert(this.name);
}

var person1=new Person('Byron');
var person2=new Person('Frank');

person1.share.push(1);
person2.share.push(2);
console.log(person2.share); //[1,2]

       实际上当代码读取某个对象的某个属性的时候,都会执行一遍搜索,目标是具有给定名字的属性,搜索首先从对象实例开始,如果在实例中找到该属性则返回, 如果没有则查找prototype,如果还是没有找到则继续递归prototype的prototype对象,直到找到为止,如果递归到object仍然没有则返回错误。 同样道理如果在实例中定义如prototype同名的属性或函数,则会覆盖prototype的属性或函数。

function Person(name){
    this.name = name;
}
Person.prototype.share=[];

var person1 = new Person('Byron');
var person2 = new Person('Frank');

person1.__proto__.share.push(1);
person2.__proto__.share.push(2);
console.log(person2.share); //[1,2]

person1.share = 'test';

console.log(person1.share) //'test'
console.log(person2.share) //[1,2]

 

 

 

参考:https://www.cnblogs.com/socool-hu/p/5665270.html

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值