`

Javascript面向对象-- 1-- 【基础-function对象和prototype--原型链-封装】

阅读更多

1. 在javascript中,function也是一个对象,具有二重性,即,可以被调用,也可以被作为普通对象来使用.

    当function作为方法时,在其名称后面加上(),即可完成方法调用.

    当function作为对象时,它具有一系列的方法和属性

 

   定义一个function可用如下方法:

   

function func(x) 
{
    alert(x);
}
func(“blah”);
 

 

或者也可以用:

 

var func = function(x)
 {
    alert(x);
};
func(“blah2”);
 也可以用:

 

 

var func = new Function(“x”, “alert(x);”);
func(“blah3”);
 这种方式,使用函数对象的构造函数Function了构造一个function对象.

 

关于Function对象,可参考 http://www.w3school.com.cn/js/pro_js_functions_function_object.asp

 

2. Javascript中没有类(class)

如果要在javascript中定义一个class需要使用function

比如:

	function Person(name,age)
	{
		this.name= name;
		this.age= age;
	}

 

 这里就定义了一个Person类.

 

当需要一个Person实例的时候,可以使用new关键字.

比如: 

 

aGuy = new Person('jack',29);
 
“new”运算符执行的操作很简单。首先,它创建一个新的空对象。然后执行紧随其后的函数调用,将新的空对象设置为该函数中“this”的值。换句话说,可以认为上面这行包含“new”运算符的代码与下面两行代码的功能相当:
var aGuy = {}; 
Person.call( aGuy, “Spot”);
上面两种方式创建的aGuy对象时不同的,new方式创建的对象属性更多,具体可使用chrome,调用console.log(aGuy);查看
第一种:
Person
  1. age29
  2. name"jack"
  3. __proto__Person
    1. constructorfunction Person(name,age)
    2. __proto__Object
第二种:Object {name: "jack", age: 29}
(注: 
call方法是Function对象的一个方法,类似的还有apply方法,
call方法参数不确定,第一个参数是要传递到函数中作为this的,从第二个参数开始,对应要调用函数的参数
apply方法参数有两个,第一个参数和call第一个参数相同,第二个参数是一个数组,保存需要传递到调用函数的参数.

 

3. 为javascript类添加方法

 

(1)第一种方式,在作为class的function中,将一个function作为方法,比如:

// Think of this as class Dog
function Dog(name) {
    // instance variable 
    this.name = name;
    // instance method? Hmmm...
    this.respondTo = function(name) {
        if(this.name == name) {
            alert(“Woof”);        
        }
    };
}

var spot = new Dog(“Spot”);

 这里的respondTo就定义了一个方法.

在上面的 Dog 定义中,我定义了名为 name 的实例变量。使用 Dog 作为其构造函数所创建的每个对象都有它自己的实例变量名称副本(前面提到过,它就是对象词典的条目)。这就是希望的结果。毕竟,每个对象都需要它自己的实例变量副本来表示其状态。但如果看看下一行,就会发现每个 Dog 实例也都有它自己的 respondTo 方法副本,这是个浪费;您只需要一个可供各个 Dog 实例共享的 respondTo 实例!通过在 Dog 以外定义 respondTo,可以避免此问题,如下所示:

function respondTo() {
    // respondTo definition
}

function Dog(name) {
    this.name = name;
    // attached this function as a method of the object
    this.respondTo = respondTo;
}

 

(2)第二种方式,需要先了解 javascript的原型(prototype)

 

   每一个function都有一个属性prototype(原型),这个prototype属性也是一个对象,它也有自己的prototype属性,这样       就形成了prototype链(原型链),这个原型链的终点是Object.prototype,因为Object.prototype指向null.

 

函数(function)的prototype对象有一个constructor属性,指向function,这样就形成了循环引用.

 

var spot = new Dog(“Spot”);

// Dog.prototype is the prototype of spot
alert(Dog.prototype.isPrototypeOf(spot));

// spot inherits the constructor property
// from Dog.prototype
alert(spot.constructor == Dog.prototype.constructor);
alert(spot.constructor == Dog);

// But constructor property doesn’t belong
// to spot. The line below displays “false”
alert(spot.hasOwnProperty(“constructor”));

// The constructor property belongs to Dog.prototype
// The line below displays “true”
alert(Dog.prototype.hasOwnProperty(“constructor”));

 当您尝试访问对象的属性/方法时,JavaScript 将检查该属性/方法是否是在该对象中定义的。如果不是,则检查对象的原型。如果还不是,则检查该对象的原型的原型,如此继续,一直检查到 Object.prototype。

 

JavaScript 动态地解析属性访问和方法调用的方式产生了一些特殊效果:

  • 继承原型对象的对象上可以立即呈现对原型所做的更改,即使是在创建这些对象之后。
  • 如果在对象中定义了属性/方法 X,则该对象的原型中将隐藏同名的属性/方法。例如,通过在 Dog.prototype 中定义 toString 方法,可以改写 Object.prototype 的 toString 方法。
  • 更改只沿一个方向传递,即从原型到它的派生对象,但不能沿相反方向传递。

  下面这个例子显示了如何解决前面遇到的不需要的方法实例的问题。通过将方法放在原型内部,可以使对象共享方法,而不必使每个对象都有单独的函数对象实例。在此示例中,rover 和 spot 共享 getBreed 方法,直至在 spot 中以任何方式改写 toString 方法。此后,spot 有了它自己版本的 getBreed 方法,但 rover 对象和用新 GreatDane 创建的后续对象仍将共享在 GreatDane.prototype 对象中定义的那个 getBreed 方法实例。

function GreatDane() { }

var rover = new GreatDane();
var spot = new GreatDane();

GreatDane.prototype.getBreed = function() {
    return “Great Dane”;
};

// Works, even though at this point
// rover and spot are already created.
alert(rover.getBreed());

// this hides getBreed() in GreatDane.prototype
spot.getBreed = function() {
    return “Little Great Dane”;
};
alert(spot.getBreed()); //当前对象覆盖了prototype中的getBreed(),但是不影响其他从prototype///继承的getBreed(),因为其他对象并没有覆盖这个方法
// but of course, the change to getBreed 

// doesn’t propagate back to GreatDane.prototype

// and other objects inheriting from it,

// it only happens in the spot object

alert(rover.getBreed());

 

 

参考:http://msdn.microsoft.com/zh-cn/magazine/cc163419.aspx

参考: http://www.ruanyifeng.com/blog/2010/05/object-oriented_javascript_encapsulation.html

分享到:
评论

相关推荐

    JavaScript的原型继承详解

    既然是面向对象的,那就有面向对象的三大特征:封装、继承、多态。这里讲的是JavaScript的继承,其他两个容后再讲。 JavaScript的继承和C++的继承不大一样,C++的继承是基于类的,而JavaScript的继承是基于原型的。 ...

    privatization:为 Javascript 中的对象添加封装

    为 Javascript 中的对象添加封装。 安装 npm install privatization --save 用法 带有要封装的方法和数据成员的对象作为第一个参数传入函数privatize(target [, prefix]) 。 在下面的例子中,原型被传入。前缀是...

    JavaScript面向对象(极简主义法minimalist approach)

    1 封装 这种方法不使用 this 和 prototype,代码部署起来非常简单,这大概也是它被叫做”极简主义法”的原因。 首先,它也是用一个对象模拟”类”。在这个类里面,定义一个构造函数 createNew (),用来生成实例。 ...

    extend:ES5 面向对象编程,构造函数继承的封装

    Extendv1.0.0ES5 面向对象编程,构造函数继承的封装。Install/安装克隆这个项目的源码或者下载压缩文件文件后,引入build文件夹内的 extend.mini.js 即安装完成。[removed][removed]Using/使用例子: // 构造函数1 ...

    leetcode和oj-jsjudo:做一些JavaScript柔道

    继承是指对象能够从父对象(Function)继承方法和属性。 什么是封装? 将对象的所有功能封装在该对象中,以便对象的内部工作(其方法和属性)对应用程序的其余部分隐藏。 什么是多态? 对象可以共享相同的接口(如何...

    Javascript Function对象扩展之延时执行函数

    扩站Function对象增加delay方法如下: 代码如下: Function.prototype.delay=function(this1,timeout){ this1=this1||null; timeout=timeout||0; var _this=this; var args=[]; //获取参数,注:第1、第2个参数是保留...

    JavaScript编程中实现对象封装特性的实例讲解

    1.prototype对象 1.1构造函数的缺点 JavaScript通过构造函数生成新对象,因此构造函数可以视为对象的模板。实例对象的属性和方法,可以定义在构造函数内部。 function Cat (name, color) { this.name = name; ...

    Javascript学习笔记9 prototype封装继承

    } Person.prototype.SayHello = function () { alert(this.name + “,” + this.age); }; var Programmer = function (name, age, salary) { Person.call(this, name, age); this.salary = salary; };

    程序员面试刷题的书哪个好-FrontEnd--Interview:自己收集整理的一些关于前端面试的问题

    当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么他就会去prototype里找这个属性,这个prototype又会有自己的prototype,于是就这样一直找下去,也就是我们平时所说的原型链的概念。 特点:...

    JavaScript实现多态和继承的封装操作示例

    本文实例讲述了JavaScript实现多态和继承的封装操作。分享给大家供大家参考,具体如下: 封装Encapsulation 如下代码,这就算是封装了 (function (windows, undefined) { var i = 0;//相对外部环境来说,这里的i就算...

    简单理解JavaScript中的封装与继承特性

    1.门户大开型,是实现对象的最基础的方法,所有方法与变量都是共有的外界可以访问。 var Book = function(name){ if(this.check(name)){ console.log(error); throw new Error(name null); } this.name = name...

    javascript封装的sqlite操作类实例

    本文实例讲述了javascript封装的sqlite操作类。分享给大家供大家参考。具体如下: function sql(name,v,desc,size,tables){ this.db=null; this.name=name; this.v=v; this.desc=desc; this.size=size; this....

    JavaScript利用构造函数和原型的方式模拟C#类的功能

    代码如下: //构造函数 function person(name, age) {... } //定义person原型,原型里的属性可以被自定义对象引用 person.prototype = { getName: function () { return this.name; }, getAge: function () { 

    AJAX之Prototype入门学习.docx

    其对现有的部分 Javascript 对象比如 Object 、 Function 、 Dom 、 String 等进行扩展,并且对 Ajax 应用进行封装,借此提供了兼容标准的更加易于使用的类库,极大的方便开发人员快速创建具备高度交互性的 Web2.0 ...

    JavaScript对象链式操作代码(jquery)

    虽然现在慢慢减少了对jQuery的使用(项目上还是用,效率高点。平时基本不用了),希望从而减少... } k.fn = k.prototype = { init:function() { this.length = 0; //var args = Array.prototype.slice.call(arguments,0

    JavaScript的继承的封装介绍

    第二个不存在的情况下,就创建类 * 当调用此函数时,传入了两个参数,第一个参数为基类,第二个参数则在基类的基础上添加内容 */ function extend(obj,prop){ function F(){ } //如果第一个参数为object类型(即json对象)...

    JavaScript 封装Ajax传递的数据代码

    代码如下:var paramBeanList = new Array(); Array.prototype.addParamBean=function...= -1) { this[index] = paramBeanObj; } else { this.push(paramBeanObj); } }; Array.prototype.clear=function(){ if

    jquery插件使用方法大全

    Jquery是继prototype之后又一个优秀的Javascrīpt框架。它是轻量级的js库(压缩后只有21k) ,它兼容CSS3,还兼容各种浏览器 (IE 6.0+, FF 1.5+, Safari 2.0+, Opera 9.0+)。jQuery使用户能更方便地处理...

    极简主义法编写JavaScript类

    下面就介绍如何使用极简主义法完成JavaScript的封装和继承 1. 封装  首先,它也是用一个对象模拟”类”。在这个类里面,定义一个构造函数createNew(),用来生成实例。 var Cat = { createNew: function(){ // ...

    用方法封装javascript的new操作符(一)

    先看个例子: 代码如下: var Class = { create : function () { return ... 这是很多jser构建类和实例化对象的过程, 细心的人会发现: 实例化的a会多一个initialize方法。initialize在实例化时做为代理在实例化后就没

Global site tag (gtag.js) - Google Analytics