函数

函数是JavaScript中特殊的对象,对函数执行typeof运算会返回字符串"function",因为函数也是对象,他们可以拥有属性和方法。

静态方法

函数在JS中定义了类的名字,任何添加到函数的属性都是类字段和类方法(类比Java中类的static variable 和 static method),下面代码起到Java里面static method的效果:

		var foo = function(){};
foo.printLog = function(){
if (arguments.length != 0)
{
console.log(Array.prototype.join.call(arguments, " - "));
}
};
foo.printLog("Test", "Static Method");

构造函数

如果函数或者方法的调用之前加上new关键字,他就构成了构造函数的调用.,

构造函数的调用和普通函数,方法的调用在实参处理,调用上下文和返回值方面有不同

(1).实参处理不同

凡是没有形参的构造函数调用都可以省略圆括号

(2)调用上下文的不同

调用构造函数创建一个新的空对象,这个对象继承自构造函数的prototype(原型).构造函数试图初始化这个新对象,并把这个新对象当做构造函数的调用上下文,所以在构造函数中this关键字可以用来引用这个新对象,也就能够在构造函数中初始化这个新对象.

注意: 尽管构造函数看起来像一个方法调用,它依然会使用这个新对象作为调用上下文。也就是说,在表达式new
o.m() 中,调用上下文并不是o.

例子1-2:

		function A()
{
this.a = 123;
this.init();
}
A.prototype = {
get: function(){console.log('The value of A is ' + this.a);},
init: function(){
console.log('do init here');
this.a=567;
}
}
var obj = new A;
obj.get();

(3)返回值不同

构造函数通常不使用return关键字调用完毕之后会返回一个对象(就是新创建的这个对象)

this关键字

this是一个关键字,不是变量也不是属性.

this关键字没有作用域的限制,他只有下面几种情况

(1)一个函数被当做方法调用,则函数中的this指向的是调用它的对象

(2)一个函数被当做函数调用,则函数中的this指向的全局对象(非严格模式)或者是undefined(严格模式下)

(3)函数被当做构造函数调用,this就指向构造函数创建的新对象

例子:

		var a = {name:'frank',age:30};//创建一个新对象
function A()
{
console.log(this);
}
A.call(a); //对象a的方法调用:this代表对象a,因为通过call的调用上下文是a
A();//全局函数调用:this代表全局变量window
new A();//构造函数调用: this代表新创建的对象A {}

函数原型,每一个函数都包含一个prototype属性,而且这个prototype包含唯一一个属性constructor指向构造函数对象,当将函数用做构造函数的时候,新创建的对象会从原型对象上继承属性,按照惯例,构造函数首字母要大写:

		function Foo(){};//Constructor

		Foo.prototype = {
constructor:Foo;//因为重写了prototype,需要显示的将constructor定义在此
userName:"Frank"};
var fooInstance = new Foo();
console.log(fooInstance.userName);//As an instance of Foo, it inherited all attributes from Foo's prototype
console.log(Foo.userName);// 函数对象Foo并没有userName属性,所以是undefined,但是Foo的原型对象有,并且被fooIntance继承
console.log(fooInstance.constructor === Foo);

注意:每个函数自身就是个对象,所以可以被赋值和像参数一样传递,但同时,它也可以被用作构造函数,用来创建其他对象。

构造函数的prototype是被所有实例共享的,例如:

<script type="text/javascript">
function Person(){};
Person.prototype =
{
constructor : Person,
name : "Frank",
friends : ["Coco","Nancy"],
sayName: function(){ alert(this.name);}
};
var p1 = new Person();
var p2 = new Person();
p1.friends.push("Van");
console.log(p1.friends);
console.log(p2.friends);
p1.sayName(); </script>

因为p1和p2共享prototype对象,所以p1的friends改变会影响到p2,这显然不是我们想要的,我们希望每个Person实例有自己单独的属性,但同时,我们又希望对一些公共方法可以共享,以节省内存。

构造方法和原型组合模式

构造方法用于定义实例属性,而原型模式用于定义方法和共享的属性。结果,每个实例都会有自己的一份实例属性的副本,同时又共享着对方法的引用,最大限度地节省了内存。有点类似于继承,但区别是prototype是单例的。

修改后的写法:

<script type="text/javascript">
function Person(name, friends){
this.name = name;
this.friends = friends;
};
Person.prototype =
{
constructor : Person,
sayName: function(){ console.log(this.name);}
};
var p1 = new Person("Frank",["coco","nancy"]);
var p2 = new Person("Daniel",["coco","nancy"]);
p1.friends.push("Van");
console.log(p1.friends);
console.log(p2.friends);
p1.sayName();
p2.sayName();
</script>

函数直接量(function literal),匿名函数 (anonymous function)

作为命名空间的函数

在函数中声明的变量在整个函数体内都是可见的,在函数的外部是不可见的(局部变量)。不在任何函数中声明的变量是全局变量,在整个JavaScript程序中都可见。

一种惯用法是用自调用匿名函数(self-invoking anonymous function) 来实现这个命名空间技术,其写法如下

function(){

//模块代码

})();

因为默认情况下,JS是运行在全局的namespace下,而对全局变量的暴露是非常危险的,因为任何无意的修改和覆盖都会来带意想不到的错误。因此在JS开发中,尽量不要定义全局变量。在JS框架开发中此条法则体现的尤为明显,因为假如框架暴露过多的全局变量,一旦被用户修改,就可能导致框架不可用。

所以在JQuery中,整个框架通过 window.jQuery = window.$ = jQuery; 只向外部暴露了2个全局变量,即著名的$和JQuery

详细请见jQuery源码分析: http://nuysoft.iteye.com/blog/1177451

对象

JavaScript 中,除了数字、true、false、null和undefined之外,其他值都是对象,每个对象拥有三个相关的对象属性(object attribute)

  • 对象的原型(prototype)指向另一个对象,本对象的属性继承自它的原型对象。对象继承是通过原型链实现的
  • 对象的类(class)是一个标识对象类型的字符串
  • 对象的扩展标记(extensible flag)指明了是否可以向该对象添加新属性

对象继承


所有通过对象直接量(Object literals)创建的对象都具有同一个原型对象Object.prototype,对象的属性继承自原型对象,对象之所以会继承是因为属性的查询过程是,搜索对象的原型链,直到根原型,如果还没有找到标识为undefined。
		var o = {};// o 从 Object.prototype 继承对象属性
o.x =1; // 定义新属性x
var p = inherit(o);//p继承o和Object.prototype
p.y = 2;
var q = inherit(p);//q继承p、o和Object.prototype
q.z =3 ;
console.log(q.x + q.y);
console.log(q.toString() + q.a);//toString继承自Object.prototype, q.a is undefined function inherit(parent){
f = function (){};//定义一个空构造函数
f.prototype = parent; //将其原型属性设置为p
return new f();//使用f()创建p的继承对象
};

上面代码对象在内存中的示意图:



对象工厂

工厂方法这个设计模式在JS中也是经常用到,下面以jQuery源码为例,看一下对象工厂的运用。

	<script language="javascript">
console.log("Start"); (function(window){//自调用函数
var //定义本地变量
core_version = "1.0.0", jQuery = function(){//这是一个工厂方法,专门用来产生jQuery对象
return new jQuery.fn.init();//下面的prototype赋值使得init函数和jQuery函数据有相同的prototype,即jQuery对象
}; jQuery.fn = jQuery.prototype = {
jquery: core_version,
constructor: jQuery,
init: function(){
return this;
},
debug: function(){console.log("debugging")}
}; // Give the init function the jQuery prototype for later instantiation
jQuery.fn.init.prototype = jQuery.fn; window.jQuery = window.$ = jQuery;//将本地变量jQuery设置为全局变量
}(window));//传入全局变量window $().debug();//$()将返回一个通过工厂方法产生的对象。
console.log("Current version is "+$().jquery);
</script>

版权声明:本文为博主原创文章,未经博主允许不得转载。

Javascript函数、构造函数、原型、类和对象的更多相关文章

  1. c++中在一个类中定义另一个只有带参数构造函数的类的对象

    c++中在一个类中定义另一个只有带参数构造函数的类的对象,编译通不过 #include<iostream> using namespace std; class A { public:  ...

  2. Effective JavaScript Item 51 在类数组对象上重用数组方法

    Array.prototype对象上的标准方法被设计为也能够在其他对象上重用 - 即使不是继承自Array的对象. 因此,在JavaScript中存折一些类数组对象(Array-like Object ...

  3. Java面向对象(概述,构造函数,类与对象的关系,this关键字,成员、局部),匿名对象的调用,构造代码块(5)

    Java面向对象(概述,构造函数,类与对象的关系,this关键字,成员.局部),匿名对象的帝爱用,构造代码块(5)

  4. JAVA基础语法:函数(方法)、类和对象(转载)

    4.JAVA基础语法:函数(方法).类和对象 函数 在java中函数也称为方法,是一段具备某种功能的可重用代码块. 一个函数包括这几部分: 函数头 函数头包括函数访问修饰符,函数返回值类型, 函数名, ...

  5. 深度剖析前端JavaScript中的原型(JS的对象原型)

          这张图片有点劝退了,哈哈哈~    通过原型机制,JavaScript 中的对象从其他对象继承功能特性:这种继承机制与经典的面向对象编程语言的继承机制不同.本文将探讨这些差别,解释原型链如 ...

  6. 如何在JavaScript中手动创建类数组对象

    前言 关于什么是js的类数组对象这里不再赘述.可以参考这个链接,还有这里. js中类数组对象很多,概念简单的讲就是看上去像数组,又不是数组,可以使用数字下标方式访问又没有数组方法. 例: argume ...

  7. 常用Javascript函数与原型功能收藏

    // 重复字符串 String.prototype.repeat = function(n) { return new Array(n+1).join(this); } // 替换全部 String. ...

  8. JavaScript篇 深入理解JavaScript函数

    JavaScript中的函数 1. 函数的定义 两种定义形式: 通过函数定义表达式来定义 通过函数声明语句来定义 函数声明语句定义一个函数 //计算阶乘的递归函数 function factorial ...

  9. javascript 函数详解2 -- arguments

    今天我们接着上篇文章来继续javascript函数这个主题.今天要讲的是函数对像中一个很重要的属性--arguments. 相关阅读: javascript 函数详解1 -- 概述 javascrip ...

  10. C++类与对象(05)

    类是具有惟一标识符的实体:在类中声明的任何成员不能使用extern.auto和register关键字进行修饰:类中声明的变量属于该类,在某些情况下,变量也可以被该类的不同实例所共享. 访问权限用于控制 ...

随机推荐

  1. c++构造函数的作用---13

    原创博客:转载请标明出处:http://www.cnblogs.com/zxouxuewei/ http://blog.csdn.net/tidyjiang/article/details/52073 ...

  2. 《C与指针》第四章练习

    本章问题 1.Is the following statement legal?If so,what does it do? (下面的语句是否合法,如果合法,它做了什么) 3 * x * x - 4 ...

  3. 练习2:雨淋湿了一道题,9个数字只能看清楚4个,第一个肯定不是1 [X * (Y3 + Z)]^2 = 8MN9,求出各个数字

    题目上的X代表的未知数,不一定是同一个数字. 其实这道题,直接一推敲答案就出来了,首先,积德尾数是9,说明 X*(Y3 + Z)的值尾数是3,3的因子只有1和3,所以X只有1和3候选,但是题目说第一个 ...

  4. Unity3D基础知识梳理

    这段时间在做Unity的项目,这差不多是我的第一次实战啊~然后公司来了实习的童鞋要学Unity,但是我一向不靠谱啊,所以只能帮他们稍微梳理下基础的东西了啊,唉~学长只能帮你们到这里了~顺便就把自己这两 ...

  5. SSAS处理时“找不到属性键”的解决办法 (转载)

    在SSAS中,经常会遇到“Attribute key not found(找不到属性键)”的错误,这种错误通常是由于某个维度属性(Dimension Attribute)的数据没能从Sql Serve ...

  6. git配置管理

    生成 SSH 公钥 如前所述,许多 Git 服务器都使用 SSH 公钥进行认证. 为了向 Git 服务器提供 SSH 公钥,如果某系统用户尚未拥有密钥,必须事先为其生成一份. 这个过程在所有操作系统上 ...

  7. 严格模式use strict

    严格模式主要有以下限制: 变量必须声明后再使用函数的参数不能有同名属性,否则报错不能使用with语句不能对只读属性赋值,否则报错不能使用前缀0表示八进制数,否则报错不能删除不可删除的属性,否则报错不能 ...

  8. 【转】maven核心,pom.xml详解

    感谢如下博主: http://www.cnblogs.com/qq78292959/p/3711501.html maven核心,pom.xml详解 什么是pom?    pom作为项目对象模型.通过 ...

  9. JavaScript常用函数和方法

    alert('Hello World!') //方法用于显示带有一条指定消息和一个 OK 按钮的警告框. //定义js函数 function Foo(name) { console.log(name) ...

  10. 使用Python xlwt写excel文件

    如果需要使用Python写Excel文件,首先下载或者安装xlwt. pip install xlwt 下面的这些demo应该可以帮助开发者快速上手使用xlwt写Excel文件: 创建工作簿(work ...