文档章节

JavaScript 面向对象基础

learn_more
 learn_more
发布于 2014/10/12 14:34
字数 2458
阅读 41
收藏 1

1  关于对象的

1  关于对象的静态属性、私有属性、局部变量、原型变量 的使用与区别

1)局部变量:是指在函数中用 var 声明过的变量,在函数运行完之后内存被自动回收!

2)私有属性:是指在函数中用 this 标记过的变量,在实例对象后一直被对象所独有!

3)静态属性:是指函数(类)本身所独有的属性,他是不能被实例对象所调用的,这与java不同。

4)原型变量:是指通过类或者对象本身的原型所所创建的变量,他能被所有的实例对象以及类本身原型所共享。

具体如下:

function Person( ){ 
this.name = 'zhangsan' ;                        // 私有属性
var value = 'wuyun' ;                             // 局部变量
this.process  = function(){                    // 使用方法    
console.info(this.name + value ); // 如果局部变量和私有变量同名,那么会使用局部变量,所以使用this作为标记!
 }}
var person = new Person( );
console.info(   person.__proto__  == Person.prototype   );  // true,说明二者可以通过原型相互共享属性
Person.age = 21 ;                                          // Person的静态属性,person是无法调用的
person.age = 22 ;                                         // person的静态属性,Person是无法调用的
Person.prototype.sex = 'man' ;                  // 原型变量,二者共享
person.__proto__.height = 185 ;               // 原型变量,二者共享


2 关于prototype 和 __proto__ 的调用

1)prototype 是Function对象独有的属性,也就是说只有类才能够调用这个属性

2)__proto__  是实例对象独有的属性,也就是用new,或者{ } 声明过的变量才能调用

3)以上二者如果是对应类的实例的话,那么他们引用的是同一个原型,所以 person.__proto__ == Person.prototype  为 true


3 关于原型链继承(必不可少的两步)

1)子类的原型指向父类的实例,SubClass.prototype = new SuperClass( );

2)子类的原型构造函数指向子类本身,SubClass.prototype.constructor = SubClass ; 

3 ) 由于js使用原型继承导致,构造函数也别继承,然而面向对象来说这是错误的,所以才有第二步重新指向构造函数。

4 ) 个人理解 Person 与 Person.prototype 的差异是:前者是指构造函数或类本身,后者其实是一个所有实例都共享的实例对象。

5)如果单纯只是继承某一个函数那么可以使用 call 函数进行处理,而无需继承。 Class.method.call(Self , param) ; 

具体如下:

function extends( SubClass , SuperClass){
/*第一步 : 构建桥梁类Bridge,他的作用就是完全替代父类本身,包括构造方法*/
var Bridge = function( ){ } ;Bridge.prototype = new SuperClass( );
 // Bridge.prototype.constructor = SuperClass ;这一步原型链默认完成 
 /*第二步 : 使用子类的原型链继承桥梁父类*/
 SubClass.prototype = new Bridge( );  SubClass.prototype.constructor = SubClass ; 
  /*第三步 : 扩展子类属性,把父类的引用作为子类的共享属性,为子类中所调用 */
  SubClass.prototype.superClass = SuperClass.prototype ;     
 //  这里必须是prototype,而不能是函数本身
 /*第四步 : 为保证程序正常运行机制,做个小判断*/
 if( SuperClass.prototype.constructor == Object.prototype.constructor  ){SuperClass.prototype.constructor = SuperClass ;} }


6)javascript是单继承的,但如果想在一个类中拥有多个类的方法,那么就要使用聚合(掺元类,把其他类的方法为自己所用)。


4 关于接口的三种模仿方式

1)注释式模仿接口(其实就是用注释语句把接口给解释,说白了就是通过规范文档来说明某给类就是一个接口),如下/*  这里就是接口的注释声明文档,这个是核心

interface Composite {    function add(child);    function remove(child);    function getChild(index);}interface FormItem {    function save();} */

var CompositeForm = function(id, method, action) { //自定义任意一个类,用来模拟实现接口

    ...

};

CompositeForm.prototype.add = function(child) { // 通过实现方法说明实现接口

    ...

};

2)属性检查式模仿接口(同样使用注释,但是它与上面的唯一不同点就是在方法的实现中,对该类有个判断是否实现了该接口,所谓判断,就是该类有一个属性用来保存他实现类的名称,所以称之为属性检查)function addForm(formInstance) {    if(!implements(formInstance, 'Composite', 'FormItem')) {        throw new Error("Object does not implement a required interface.");    }    ...}3)鸭式辨型式模仿接口(它采用的思想是说只要在实现类中实现了接口中的所有方法就等同于实现了接口,那么他的核心就是判断是否实现了接口中的方法,否则报错)


5 创建对象的模式(成员变量的保护)

1)门户大开型(使用 this.property 的方式定义成员变量,但是为了成员数据的安全性,我们使用接口实现,只能调用接口来访问成员变量,不过这必须自觉遵守,因为本身是可以直接通过instance.property 调研的)function Book( id , name ){this.setId(id); //使用接口方法对属性赋值,而不是直接赋值属性this.setName(name);}Book.prototype = {  // 通过字面量方式注册实现接口的方法,同时还使用检查规则,这样就避免了自己赋值属性导致的问题setId:function(id){this.checkId(id); // 这个才是核心this.id = id ;}check:function(id){// some code}.......}2)用户命名规范区别私有成员(这种方法其实和上面的方法是一模一样的,唯一的差异就在于对象的成员变量名称都用下划线开头,一些不希望外部调用的方法也使用下划线开头,说白了这就是约定俗成,并不是真正的达到目的)如下:Book.prototype = { // 通过字面量方式注册实现接口的方法,同时还使用检查规则,这样就避免了自己赋值属性导致的问题setId:function(id){this._checkId(id); // 这个才是核心this._id = id ;

}

_check:function(id){

// some code

}

.......

}

3)使用闭包函数实现真正的私有成员(这种做法就是充分借用函数作用域以及闭包原来达到私有成员变量的保护)

1)函数作用域:在javascript中只有函数作用域没有块级作用域,换句话说,如果A函数内部有个B函数,那么B函数是能够调用A函数的所有成员的。

2)闭包:对以上的A B , 如果在B中使用了A的成员变量,不管B在哪里执行,是在A内部执行,或是在A外部的任意函数作用域中执行,B所执行的作用域还是A,也就是说不管A是否执行完,A都会为B保留一份执行空间的内存,那么B使用A的成员变量将会被保留。这就是说 在不同函数作用域中也能调用之前作用域的成员变量,为闭包!

3)使用函数作用域和闭包的概念完成私有成员的保护:

var Book = function(newIsbn, newTitle, newAuthor) { // implements Publication  // Private attributes. 私有成员变量  var isbn, title, author;  // Private method. 私有方法  function checkIsbn(isbn) {    ...  }  // Privileged methods. 公共方法  this.getIsbn = function() {    return isbn;  };  this.setIsbn = function(newIsbn) {    if(!checkIsbn(newIsbn)) throw new Error('Book: Invalid ISBN.');    isbn = newIsbn;  };  // Constructor code. 初始化  this.setIsbn(newIsbn);};// Public, non-privileged methods. 公共共享方法Book.prototype = {  display: function() {    ...  }};

这里很值得注意的是:使用 var 声明的变量就是为私有的属性,因为没有使用this标记所以是无法再外部调用的,但是通过闭包达到私有变量的保护有个很大的缺点就是:公共方法(为了闭包)写在了类里面,从而导致每个对象实例化后都会保存这个方法的副本,那么导致占了大量内存,如果把方法写在prototype中,即成为公共共享的方法,只保存一份副本在内存,但是在公共共享的方法中只能使用this来调用变量,而不能调用用var声明的变量。所以这就是这种方法的弊端!而且还有一个弊端就是:继承该类之后的子类是不能访问到该类的私有成员的,因为只能使用闭包访问了!!!


6 关于属性和方法的相关概念

1)实例公共属性: this.name

2)实例私有属性: person.name(单个实例);var name ( 所有实例 )

3)类公共属性:Person.name ; 

4 ) 静态属性:Person.prototype.name ; person.__proto__.name ;

5)使用闭包重新定义属性的概念:

var Person = ( function( ){var name = ''; //类的静态私有属性this.sex = '';   // 类的静态共有属性var ocr = function( ){var age = ''; //实例私有属性this.height = ''; //实例共享属性}ocr.getName = function( ){ //定义类的方法return name ;}return ocr ; //返回的是类本身} )( )alert(Person.getName( ));

这里说说执行流程:1)使用小括号就是为了让他自动执行,这里直接使用Person,实际上已经把Person定义的function执行完成了,等价于没有小括号时的,Person();

                               2)返回一个function,实际上就是闭包的原理,也可以看成就是返回一个类,是这个类本身而不是类实例,所以我们定义方法是用类名定义类的属性,而不是定义实例属性,不然的话无法在外面调用。


7 常量(就是使用属性的定义以及闭包原理)


8 函数的链式调用

1)所谓链式调用不过就是可以person.fn( ).process( ).property ;

2)实现很简单,就是在每一个方法的返回值为当前实例,即 this ; 

3)关于Jquery 的链式调用,如下:

//为了类(Function)扩展函数,我们顶一个他的静态函数

Function.prototype.method = function(name,fn){ // Function.prototype是为所有的Function对象增加属性,原因是继承

 this.prototype[name] = fn;  // 这里的this是指函数类本身,所以要用prototype,这样才能使属性共享  return this;  // 返回this,达到链式调用

};


© 著作权归作者所有

learn_more
粉丝 93
博文 240
码字总数 210196
作品 0
深圳
程序员
私信 提问
分享51本关于JavaScript方面的学习书籍(免费下载)

分享51本关于JavaScript方面的学习书籍(免费下载) 1、JavaScript面向对象15分钟教程 2、原型、作用域、闭包的完整解释 3、Javascript面向对象特性实现(封装、继承、接口) 4、JavaScript面向...

邓剑彬
2012/12/02
1K
12
好程序员web前端培训分享学习JavaScript

好程序员web前端培训分享学习JavaScript,我试着总结自己学习JavaScript的方法 JavaScript给人那种感觉的原因多半是因为它如下的特点: 1、本身知识很抽象、晦涩难懂,如:闭包、内置对象、D...

好程序员IT
04/09
0
0
说说掌握JavaScript语言的思想前提

无论是公司的同事还是外界的程序员朋友们,大部分人对JavaScript的高级应用不甚了解,已有的知识架构里会认为JavaScript仅仅是一门脚本语言,其作用是给页面做一些锦上添花的效果,比如表单验...

bosscheng
2013/08/07
0
1
为什么我不建议你将JavaScript作为主力语言

在你的软件职业生涯中,JavaScript不应该成为你的首要语言 转自:ourjs.com 作者 Matthew Mombrea 1 月 09, 2014 (几天前,我写了一篇文章关于在 你的职业生涯中应该学习的编程语言。这个引起...

Kris_zcl
2014/04/15
1K
13
5 个非常有用的 JavaScript 调试工具

JavaScript被称作以原型(prototype)为基础的语言。这种语言有很多特色,比如动态和弱类型,它还有一等函数(first class function)。另一个特点是它是一个多范型(multi-paradigm)语言,支持...

tsl0922
2012/05/06
4.8K
11

没有更多内容

加载失败,请刷新页面

加载更多

uniapp + bootstrapvue 移动/PC 一套搞定 (一)配置bootstrapvue

1.准备文件 自己到DCloud官网: http://dcloud.io/ 去下载官方的IDE Hbuilder,新建一个空的uniapp项目即可。 uniapp框架自带优化的vue,我们仅仅需要准备以下三个文件: bootstrap.min.css ...

panyunxing
今天
5
0
Android Camera原理之camera service类与接口关系

camera service主要是指 frameworks/av/services/camera/下面的代码,最近在看这一块的代码,为了更好地理清这一块的代码,也为了后续学习camera方便一些,我觉得很有必要理一下这一块的整体...

天王盖地虎626
今天
2
0
Golang学习笔记

[TOC] Golang学习笔记 这个学习笔记是最早在1.初,版本左右的时候写的,和当前最新的版本可能会有较大的差异. 因为成文比较早,文章里面又有很多自己的见解,有些东西当时理解的不太透彻可能写错...

我爱吃炒鸡
今天
8
0
科技赋能成效显著!金融壹账通两大赋能项目荣获IDC大奖

7月19日,2019IDC中国未来金融论坛曁颁奖典礼于北京举办。由金融壹账通赋能的长春农商银行多人视频面审智能风控系统、包头农商银行互联网银行SaaS服务两大项目因在项目的创新性、技术领先性、...

IFTNews
昨天
1
0
HTTP协议

HTTP简介 HTTP协议(HyperText Transfer Protocol,超文本传输协议)是因特网上应用最为广泛的一种网络传输协议,所有的WWW文件都必须遵守这个标准。 HTTP是一个基于TCP/IP通信协议来传递数据...

Eappo_Geng
昨天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部