prototype由来

在理解prototype前,首先得理解js面向对象编程的私有变量、私有函数,静态变量、静态函数,以及实例变量,实例函数

私有变量,私有函数

函数内部通过var定义的变量

function obj(){
    var a= 1;
    var b= function(){}
};
console.log(obj.a); //undefined
console.log(obj.b); //undefined
var o= obj();
console.log(o.a); //undefined
console.log(o.b); //undefined

这样a变量,b函数只能在函数体内部获取,外部无法获取,(无论是通过函数本身还是实例获取),所以称为私有变量

--------------------------------------------------------------------------------------------------------------------

静态变量,静态函数

函数外部通过.定义的变量(函数实质上是一种对象)

function obj(){ 
};
obj.a= 1;
obj.b= function(){};
console.log(obj.a); //1
console.log(obj.b); //function(){}
var o= new obj();
console.log(o.a); //undefined
console.log(o.b); //undefined

通过函数本身依旧能获取,但不能通过实例获取

-------------------------------------------------------------------------------------------------------------------

实例变量,实例函数

通过实例函数定义的变量,函数

function obj(){
    this.a= 1;
    this.b= function(){};
};
console.log(obj.a); //undefined
console.log(obj.b); //undefined
var o= new obj();
console.log(o.a); //1
console.log(o.b); //function(){}

不能通过实例函数获取,只能通过实例函数定义的变量获取

-------------------------------------------------------------------------------------------------------------------

总所周知,js面向对象最佳方案是通过构造函数实现(虽然通过一般函数也行),

在创建时私有变量,函数,实例变量,函数使用较多,静态变量,函数很少用,当然这只是本人的经验...

那么,进入正题,为何需要prototype?,首先请看下面的一个例子~

function obj(){
    this.a= [];
    this.b= function(){};
};
var o1= new obj();
o1.a.push(1);
var o2= new obj();
console.log(o2.a); //[]

分析:我们通过o1改变了a属性,但通过o2获取仍然不变,为何?

因为通过构造函数创建的诸个实例,是通过对此函数变量,方法的复制,彼此之间不会共享,不会互相影响

好比两人通过同一个链接下了同一部电影,其中一个修改了影片资源,那么会对另一个人造成影响么,当然不会!

那么,问题来了,当实例有几百,上千个,其变量、方法复制几百上千次,这是对资源的极大浪费!

prototype属性应运而生~请看下面实例

function obj(){
    this.a= [];
    this.b= function(){};
};
obj.prototype.c= [0];
obj.prototype.d= function(){
    console.log("0");
}
var o1= new obj();
o1.c.push(1);
o1.d= function(){console.log("1")};
var o2= new obj();
console.log(o2.c); //[0,1]
o2.d(); //0

c被更改了!证明变量,函数得以共享!(值得一提的是o1.d= function(){console.log("1")};无法改变通过prototype定义的函数,这是本人之前犯过的错)

这样定义可节约大量空间

----------------------------------------------------------------------------------------------------------------------------------------------------------------------

prototype详解:

prototype与__proto__,继承链:

依旧从一小段代码开始

function obj(){
    this.a= [];
    this.b= function(){};
};
console.log(obj.prototype);

输出:

解析:

每一个我们定义的函数都有prototype属性,prototype是一个对象,内有constructor属性及__proto__属性(注意下划线长度)

然后是下面这段:

function obj(){
    this.a= [];
    this.b= function(){};
};
var o= new obj();
console.log(o.__proto__);

解析:

每一个实例皆有__proto__属性,指向其构造函数的prototype属性!

接着这个:

function obj(){
    this.a= [];
    this.b= function(){};
};
console.log(obj.prototype);
console.log(Number.prototype);
console.log(Object.prototype);

备注:当使用number,object等基本类型时,注意首字母大写,可以把他们也理解为构造函数,函数名是Number,Object等(当然只是这么理解,真实情况当然不是这样~)

发现除了Object以外,其他类型的prototype都有__proto__属性

解析:Function,Number,String等本质都是Object的实例!因此都有__proto__属性,Object是源头,自然没有~~,而这恰恰验证了js一切皆为对象的思想!

Object>基本类型>构造函数>继承构造函数...层层向下,形成继承链!

-------------------------------------------------------------------------------------------------------------------------------------------------------

constructor(构建者):

请看代码:

function obj(){
    this.a= [];
    this.b= function(){};
};
console.log(obj.prototype.constructor);

console.log(typeof obj.prototype.constructor);

输出:

function obj(){
    this.a= [];
    this.b= function(){};
};

function

解析:函数的prototype都有constructor属性,function类型,其值指向函数本身!

保险起见,为验证是否是函数本身实验以下代码:

(通过静态属性)

function obj(){
    this.a= [];
    this.b= function(){};
};
obj.c= 1;
console.log(obj.prototype.constructor.c); //1

验证成功,真是神奇~

当然,基本类型,包括Object都有constructor属性,

console.log(Number.prototype.constructor);
console.log(Object.prototype.constructor);

输出结果为:

function Number() { [native code] }
function Object() { [native code] }

--------------------------------------------------------------------------------------------------------------------

prototype相关方法:

isPrototypeOf

判断一个实例是否存在于对象的原型链中

function obj(){
    this.a= 1;
};    
var o= new obj();
console.log(obj.prototype.isPrototypeOf(o));//true

注意:值得一提的是此方法只适用于自定义的函数!,不适用于基本类型

String.prototype.isPrototypeOf("aa");

Number.prototype.isPrototypeOf(1);

诸如此类都会返回false!

hasOwnProperty

判断实例拥有的属性是本地属性(例如 this.a)还是继承自prototype

function obj(){
    this.a= 1;
};    
obj.b= 1;
var o= new obj();
console.log(o.hasOwnProperty("a")); //true
console.log(o.hasOwnProperty("b")); //false
console.log("aaa".hasOwnProperty("length")); //true

本地属性返回true,继承自prototype返回false

此属性对基本类型有用!

in

判断实例是否拥有此属性(对本地属性,prototype属性皆有用)

function obj(){
    this.a= 1;
};    
obj.b= 1;
var o= new obj();
console.log("a" in o); //true
console.log("b" in o); //true
console.log("length" in "aaa"); //报错!

存在即返回true,

不可用于基本类型!

prototype小解的更多相关文章

  1. js闭包 和 prototype

    function test(){ var p=200; function q(){ return p++; } return q; } var s = test(); alert(s()); aler ...

  2. PHP设计模式(六)原型模式(Prototype For PHP)

    原型设计模式: 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 原型设计模式简单的来说,顾名思义, 不去创建新的对象进而保留原型的一种设计模式. 缺点:原型设计模式是的最主要的缺点就 ...

  3. Function.prototype.toString 的使用技巧

    Function.prototype.toString这个原型方法可以帮助你获得函数的源代码, 比如: function hello ( msg ){ console.log("hello& ...

  4. 分析js中的constructor 和prototype

    在javascript的使用过程中,constructor 和prototype这两个概念是相当重要的,深入的理解这两个概念对理解js的一些核心概念非常的重要. 我们在定义函数的时候,函数定义的时候函 ...

  5. C#设计模式:原型模式(Prototype)及深拷贝、浅拷贝

    原型模式(Prototype) 定义: 原型模式:用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象.被复制的实例被称为原型,这个原型是可定制的. Prototype Pattern也是一 ...

  6. 关于JS的prototype

    在接触JS的过程中,随着理解的深入会逐渐的理解一些比较深奥的理论或者知识,那么今天我们来介绍一下比较难理解的prototype和constructor. 初步理解: 在说prototype和const ...

  7. js中的原型prototype

    var arr1 = new Array(12,34,98,43,38,79,56,1); arr1.sum=function (){ var result = 0; for(var i=0; i&l ...

  8. [基础] Array.prototype.indexOf()查询方式

    背景 最近在看Redux源码,createStore用于注册一个全局store,其内部维护一个Listeren数组,存放state变化时所有的响应函数. 其中store.subscribe(liste ...

  9. prototype,__proto__,constructor

    proto属性: 所有对象都有此属性.但它不是规范里定义的属性,并不是所有JavaScript运行环境都支持.它指向对象的原型,也就是你说的继承链里的原型.通过Object.getPrototypeO ...

随机推荐

  1. ckplayer 参数设置详解

    参数   使用说明 f s=0时地为普通的视频地址s=1时是一个网址,网址里存放视频地址s=2时是一个网址,网址里输出xml格式的视频地址s=3时是一个swf文件地址,swf和播放器进行交互读取地址 ...

  2. Storm源码分析--Nimbus-data

    nimbus-datastorm-core/backtype/storm/nimbus.clj (defn nimbus-data [conf inimbus] (let [forced-schedu ...

  3. Where is the python library installed?

    configure: error: Could not link test program to Python. Maybe the main Python library has been inst ...

  4. LeetCode OJ 53. Maximum Subarray

    Find the contiguous subarray within an array (containing at least one number) which has the largest ...

  5. ckeditor 基础

    <!DOCTYPE html> <!-- Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights rese ...

  6. 转载:Ubuntu下deb包的安装方法

    转载:Ubuntu下deb包的安装方法,http://blog.csdn.net/kevinhg/article/details/5934462 deb是debian linus的安装格式,跟red ...

  7. rabbitmq——镜像队列

    转自:http://my.oschina.net/hncscwc/blog/186350?p=1 1. 镜像队列的设置 镜像队列的配置通过添加policy完成,policy添加的命令为: rabbit ...

  8. MySQL DATE_FORMAT

    MySQL   DATE_FORMAT(date,format) 根据format字符串格式化date值 (在format字符串中可用标志符: %M 月名字(January……December) %W ...

  9. sql语句的使用;

    1.导出数据库的语句: mysqldump -u root -p shop > d:\shop.sql

  10. Alyona and flowers

    Alyona and flowers time limit per test 2 seconds memory limit per test 256 megabytes input standard ...