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. Java JVM 多态(动态绑定)

    Java JVM 多态(动态绑定) @author ixenos 摘要:绑定.动态绑定实现多态.多态的缺陷.纯继承与扩展接口.向下转型与RTTI 绑定 将一个方法的调用和一个方法的主体关联起来,称作( ...

  2. 更好列表页中一个航班.先unset删除数组中一个键值对,再追加,最后按键排序

    <?php $arr = array( '0' => array('item' => array( 'aa' => 'aaa', 'bb' => 'bbb' )), '1 ...

  3. Xshell4连接,Linux系统中文显示乱码解决办法

    Xshell 是一个强大的安全终端模拟软件,它支持SSH1, SSH2, 以及Microsoft Windows 平台的TELNET NetSarang Xshell 4 Build 0120议.使用 ...

  4. 手机下的ev.pageX无效

      把  ev.pageX  换成  e.originalEvent.targetTouches[0].pageX;   例子: var start_x, start_y, end_x, end_y, ...

  5. 洛谷-A+B Problem-洛谷的第一个任务

    题目描述 Description 输入两个整数a,b,输出它们的和(a,b<=10^9)  输入输出格式 Input/output 输入格式:两个整数以空格分开输出格式:一个数  输入输出样例  ...

  6. Openjudge-计算概论(A)-找和为K的两个元素

    描述: 在一个长度为n(n < 1000)的整数序列中,判断是否存在某两个元素之和为k. 输入第一行输入序列的长度n和k,用空格分开.第二行输入序列中的n个整数,用空格分开.输出如果存在某两个元 ...

  7. TakeColor 屏幕取色器 8.0 中文绿色版

    软件名称: TakeColor 屏幕取色器软件语言: 简体中文授权方式: 免费软件运行环境: Win8 / Win7 / Vista / WinXP软件大小: 210KB图片预览: 软件简介:使用方便 ...

  8. Python 学习笔记11

    如何要飞得高,就该把天空忘掉.如果时时想着梦想,那就寸步难行.因为会产生很强的挫败感.倾空自己的杯子,把自己放空,才能放得进去东西. 这两天一直在鼓捣要用python写一个博客出来.先是下载了一个放到 ...

  9. WCF部署在IIS上

    WCF部署在IIS上 环境vs2010,WCF应用程序.如何将WCF部署在IIS上. 第一步:右键点击项目,选择生成部署包. 第二步:在你项目所在的文件目录下找到Package文件夹,这就是我们的部署 ...

  10. JPA 系列教程18-自动把firstName+lastName合并为name字段

    需求 设计的国际化网站,页面需要输入firstName,lastName,后台数据库只需要存储name属性. 页面获取的firstName,lastName持久化到数据库name属性,规则按照,分隔保 ...