prototype小解
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小解的更多相关文章
- js闭包 和 prototype
function test(){ var p=200; function q(){ return p++; } return q; } var s = test(); alert(s()); aler ...
- PHP设计模式(六)原型模式(Prototype For PHP)
原型设计模式: 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 原型设计模式简单的来说,顾名思义, 不去创建新的对象进而保留原型的一种设计模式. 缺点:原型设计模式是的最主要的缺点就 ...
- Function.prototype.toString 的使用技巧
Function.prototype.toString这个原型方法可以帮助你获得函数的源代码, 比如: function hello ( msg ){ console.log("hello& ...
- 分析js中的constructor 和prototype
在javascript的使用过程中,constructor 和prototype这两个概念是相当重要的,深入的理解这两个概念对理解js的一些核心概念非常的重要. 我们在定义函数的时候,函数定义的时候函 ...
- C#设计模式:原型模式(Prototype)及深拷贝、浅拷贝
原型模式(Prototype) 定义: 原型模式:用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象.被复制的实例被称为原型,这个原型是可定制的. Prototype Pattern也是一 ...
- 关于JS的prototype
在接触JS的过程中,随着理解的深入会逐渐的理解一些比较深奥的理论或者知识,那么今天我们来介绍一下比较难理解的prototype和constructor. 初步理解: 在说prototype和const ...
- 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 ...
- [基础] Array.prototype.indexOf()查询方式
背景 最近在看Redux源码,createStore用于注册一个全局store,其内部维护一个Listeren数组,存放state变化时所有的响应函数. 其中store.subscribe(liste ...
- prototype,__proto__,constructor
proto属性: 所有对象都有此属性.但它不是规范里定义的属性,并不是所有JavaScript运行环境都支持.它指向对象的原型,也就是你说的继承链里的原型.通过Object.getPrototypeO ...
随机推荐
- CF 604B More Cowbell#贪心
(- ̄▽ ̄)-* //把最大单独放,然后第二大的和最小的放一起,第三大的和第二小的放一起 //由此类推,求最大值,即为盒的最小值 #include<iostream> #include&l ...
- 导入excel表格的数据--->到mysql中
01下载excel类,将Classes文件夹放入ThinkPHP\Extend\Vendor\位置 下载地址 http://phpexcel.codeplex.com/releases/view/26 ...
- Caffe+Ubuntu14.04+CUDA7.5 环境搭建(新人向)指南
序 本文针对想学习使用caffe框架的纯新手,如果文中有错误欢迎大家指出. 由于我在搭建这个环境的时候参考了许多网上的教程,但是没有截图,所以文中图片大多来源于网络. 本文没有安装matlab的步骤, ...
- lnmp vps服务器删除mysql日志文件三种方法
我在上一篇文章介绍了著名的LNMP主机一键安装工具,对比了军哥lnmp和AMH主机的差别,由于AMH拥有用户后台界面,易于新手操作,值得推荐. 但是,上周末我网站宕机,收到DNSPOD发来了宕机提醒, ...
- chapter9_4 非抢占式的多线程
协同程序与常规的多线程不同之处:协同程序是非抢占式的. 当一个协同程序运行时,是无法从外部停止它的.只有当协同程序显式地调用yield时,它才会停止. 当不存在抢先时,编程会变得简单很多,无须为同步的 ...
- ios 中Category类别(扩展类)小结
类别 类别是一种为现有的类添加新方法的方式.利用Objective-C的动态运行时(runtime)分配机制,可以为现有的类添加新方法,这种为现有的类添加新方法的方式称为类别catagory,他可以为 ...
- Core Animation中的基础动画
基础动画 在开发过程中很多情况下通过基础动画就可以满足开发需求,前面例子中使用的UIView代码块进行图像放大缩小的演示动画也是基础动画(在iOS7 中UIView也对关键帧动画进行了封装),只是UI ...
- 【转】解决Windows不能在本地计算机启动apache tomcat
http://blog.163.com/ftskwsg@126/blog/static/5623853020094494117827/ 这个方法解决了我的问题. 在windows下以服务的方式启动时提 ...
- VBS基础篇 - 杂项 - Sendkeys
VBS基础篇 - 杂项 - Sendkeys 模拟键盘操作,将一个或多个按键指令发送到指定Windows窗口来控制应用程序运行 其使用格式为:object.SendKeys(string) obj ...
- Linux平台从文件中查找字符赋值于变量
以telnet方式登录Linux主机,在默认目录下用命令创建一个包含DUT wanIP的文本文件.[root] echo wanIP=88.0.100.253 > ./wanIP.txt在默认目 ...