1.用prototype 封装类

创建的每个函数都有一个prototype(原型属性),他是个指针,指向的对象,这个对象的用途就是包含了这个类型所有实例共享的属性和方法。

回味这句,想想java或者C++吧,如果func是class 类,类的类属性和类方法都放在了prototype中了

var func = function (argument) {
  // body...
};

Ok,现在就用c++面向对象的思想建立个Person类,里面有一些类成员

function Person(){

 }

 Person.prototype.say = function(first_argument) {
// body...
console.info('i say...') }; Person.prototype.age = 10;
var sy = new Person(); // new 会创建个对象,不加new 就是执行这个函数 console.info(sy.age)
sy.say()

成功实现了面向对象,sy 可以say,还有了age,当然age不应该是类属性,

Say和age 是所有 Person 所有实例共享的,假如age是数组,sy.age[1] = 10 会导致所有实例的age都变化

2.原理:定义Person function,实例化一个Person,中间有啥奥秘

定义:

function Person(){

}
  1. 只要创建个新函数,js引擎会根据一组特定的规则为该函数创建一个原型对象, prototype属性指向这个原型对象;
  2. 默认情况下,所有原型对象都会自动获取一个constructor(构造函数)属性,这个constructor指向了prototype属性所在的函数;

实例化:

new的过程拆分成以下三步:

  1. var p={}; 也就是说,初始化一个对象p
  2. p.__proto__ = Person.prototype;
  3. Person.call(p); 也就是说构造p,也可以称之为初始化p,过程中关键字 this 被设定为该实例。
  4. 返回实例
function New (f) {

    var n = { '__proto__': f.prototype }; /*第1,2步*/

    return function () {

        f.apply(n, arguments);            /*第3步*/

        return n;                         /*第4步*/

    };

}

var p2 = New (Point)(10, 20);

p2.print(); // 10 20

console.log(p2 instanceof Point); // true

sy = new Person(),创建一个新对象sy,sy实例的内部将包含一个Prototype类型的指针__proto__,指向Person函数的原型对象,实例sy和Person没直接关系,和Person.prototype才有直接关系

这里我们可以发现,prototype太重要了

      

sy.say() 看来是通过查询__proto__指向的原型来调用方法的;访问对象属性时,js会搜索改该属性,从实例sy开始,沿着原型搜索;

需要注意的是sy.age = 100, 不会修改原型的值,而是给sy添加了个属性age,以后就屏蔽了原型的age,这点和python类似。当然你可以 delete sy.age,就可以重新访问到原型属性了。当然原型的属性age不属于实例,实例也delete不掉。

有的浏览器无法访问__proto__,可以通过Person.prototype.isPrototypeOf(sy)  等于true,或者Object.getPrototypeOf(sy) == Person.prototype 判断原型和实例之间的关系s

3. 类:现在我们来实现面向对象的封装功能

function Person(name, age){
this.name = name; // 调用new的时候,创建个新的this指向当前正在构造的新实例,其他时候的this都是指向调用者s
this.age = age;
} Person.prototype.say = function(first_argument) {
console.info(this.name + ' say...')
}; var sy = new Person('suyuan', 26);
sy.say() var zl = new Person('zhuli', 27)
zl.say()

一句话,方法用原型链,类属性(数据)用构造函数

4.既然面向对象编程了,那么继承呢?

Js中的函数没有声明,只有定义,所有不支持接口继承,那我们就用原型链来实现定义(实现)继承

function Person(){
this.live = true;
} Person.prototype.say = function(first_argument) {// (4) Person的原型添加函数say
console.info('i am ' + this.live) }; function Man(){
this.manLive = true;
} var tmp_person = new Person();//(3) 实例tmp_person 的__proto__ 指向Person原型
Man.prototype = tmp_person //(2) temp_person 这个对象有say方法,Man的原型(也就是temp_person)有say方法,Man实例化出来的对象sy当然有say var sy = new Man();//(1)
sy.say()//(5)

sy是Man实例,

(1)sy的__proto__指向Man的原型,

(2)Man原型指向Person的实例tmp_person,

(3) tmp_person的__proto__指向Person原型,

(4)Person原型有函数say

(5)然后sy 就有了say方法。

在此继承就实现了。

更深入的了解,请看下一篇

http://www.cnblogs.com/suyuan1573/p/proto.html

javascript原型深入解析1-prototype 和原型链、js面向对象的更多相关文章

  1. 简单粗暴地理解js原型链–js面向对象编程

    简单粗暴地理解js原型链–js面向对象编程 作者:茄果 链接:http://www.cnblogs.com/qieguo/archive/2016/05/03/5451626.html 原型链理解起来 ...

  2. 简单粗暴地理解js原型链--js面向对象编程

    原型链理解起来有点绕了,网上资料也是很多,每次晚上睡不着的时候总喜欢在网上找点原型链和闭包的文章看,效果极好. 不要纠结于那一堆术语了,那除了让你脑筋拧成麻花,真的不能帮你什么.简单粗暴点看原型链吧, ...

  3. javascript中的this与prototype,原型理解

    JavaScript 函数调用 JavaScript 函数有 4 种调用方式. 每种方式的不同方式在于 this 的初始化. this 关键字 一般而言,在Javascript中,this指向函数执行 ...

  4. JS面向对象(2) -- this的使用,对象之间的赋值,for...in语句,delete使用,成员方法,json对象的使用,prototype的使用,原型继承与原型链

    相关链接: JS面向对象(1) -- 简介,入门,系统常用类,自定义类,constructor,typeof,instanceof,对象在内存中的表现形式 JS面向对象(2) -- this的使用,对 ...

  5. 【JavaScript】 JS面向对象的模式与实践 (重点整治原型这个熊孩子 (/= _ =)/~┴┴ )

    参考书籍 <JavaScript高级语言程序设计>—— Nicholas C.Zakas <你不知道的JavaScript>  —— KYLE SIMPSON   在JS的面向 ...

  6. 【jquery】javaScript中prototype的妙用 巧妙运用prototype属性原型链创建对象

    prototype  可以有好多有优化实现方法 http://blog.csdn.net/liuqiwen0512/article/details/8089690 在 JavaScript 中,每个函 ...

  7. Javascript之傻傻理不清的原型链、prototype、__proto__

    新人学习Javascript,其中的原型链一直是云里雾里,不得要领,查了很多相关资料,觉得这遍讲得最为清晰易懂,特转载分享,共同学习. 1. JavaScript内置对象 所谓的内置对象 指的是:Ja ...

  8. javascript原型深入解析2--Object和Function,先有鸡先有蛋

    1.提出两个问题: Js 的prototype和__proto__ 是咋回事? 先有function 还是先有object? 2.引用<JavaScript权威指南>的一段描述: 每个JS ...

  9. 全面了解 Javascript Prototype Chain 原型链

    原型链可以说是Javascript的核心特征之一,当然也是难点之一.学过其它面向对象的编程语言后再学习Javascript多少会感到有些迷惑.虽然Javascript也可以说是面向对象的语言,但是其实 ...

  10. [js高手之路]一步步图解javascript的原型(prototype)对象,原型链

    我们接着上文继续,我们通过原型方式,解决了多个实例的方法共享问题,接下来,我们就来搞清楚原型(prototype),原型链的来龙去脉. function CreateObj(uName) { this ...

随机推荐

  1. Codeforces G. The Brand New Function(枚举)

    题目描述: The Brand New Function time limit per test 2 seconds memory limit per test 256 megabytes input ...

  2. Python使用进程间共享变量来控制两个进程(监听键盘和相机录制)的交互

    我有个简单的应用需求: 1. 该应用随时会监听键盘的输入: 2. 当输入指定键时会控制相机录制的启动和关闭. 监听键盘是一个事件循环,相机录制也是一个循环录制的过程.我试着用 Python 启动两个进 ...

  3. Caused by: com.mysql.cj.exceptions.InvalidConnectionAttributeException: The server time zone value 'Öйú±ê׼ʱ¼ä'

    java.sql.SQLException: The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more ...

  4. 08-cmake语法-set()

    CMake的基本数据类型是字符串,一组字符串在一起称为列表(list) 用于设置变量. set(VAR a b c) # 输出 VAR = a;b;c VAR 就是一个list 参考: https:/ ...

  5. Windbg Memory(内存)窗口的使用

    在 WinDbg 中,可以查看和编辑内存,通过输入命令或通过使用内存窗口. 内存窗口的打开 通过菜单View-->Memory 通过快捷键Alt+5 通过工具栏 使用内存窗口 通过上面方式打开的 ...

  6. 使用plv8+ shortid npm包构建一个短唯一id服务

    plv8 是一个很强大的pg 扩展插件,我们可以直接额使用js 增强sql ,shortid 是一个用来生成短连接id 很方便的类库 因为shortid 是一个npm 模块,我们需要使用一种方法使用r ...

  7. helm repository 相关

    chart repo是一个可用来存储index.yaml与打包的chart文件的HTTP server.当要分享chart时,需要上传chart文件到chart仓库,任何一个能够提供yaml与tar文 ...

  8. 认识随机函数rand()和srand(unsigned int )

    rand函数 int rand( void ); 函数名:   rand 功   能:   随机数发生器 用   法:   int rand(void); 所在头文件: stdlib.h 函数说明 : ...

  9. python对图片批量命名

    深度学习中经常会有批量对图片进行重命名,从网上看到的资料整理一下,方便以后查看. import os class BatchRename(): ''' 批量重命名文件夹中的图片文件 ''' def _ ...

  10. c# word 插入图片问题

    情景描述: 在之前文本框中加标签,代码直接addPicture出现了意外.不起作用,怀疑是文档模板的问题,因为生成的PDF和word格式总时不时有差异,左右捣鼓下,更换文本框,更换图片形式,形状形式, ...