要么是一个数与一个集合组成的数对从定义可以

前言 在前一篇文章javascript之典型高阶函数中主要实现了几个典型的functional函数。文章最后也提出了疑问,为啥那样的实现与F#之类的函数式语言“不太一样”呢?今天来试试更“函数式”的实现。 另一种实现 同样地,尝试对之前实现的函数做一些改动,把for循环去掉。如何去掉呢?这里先要引入一个集合的归纳法定义: 一个集合要么是空集,要么是一个数与一个集合组成的数对从定义可以看到,每一个集合都可以看作为一个数和一个集合的对。例如:{1,2,4,5} 可以认为是数 1 与 集合{2,4,5} 组成的一对,写成。递归地,{2,4,5} 可以看成是。最后即为 。按照这样的理解,我们就可以用递归的方法消除循环,因为我们在分解的时候已经访问了每一个数据项,并且终结条件为空集。下面就看一下filter函数的另一个实现,原函数名加前缀f以区别之前函数: 复制代码 代码如下: function ffilter{ var i=arguments[2] || 0, out = arguments[3] || []; if return arguments[3]; if out.push; return arguments.callee; } 测试: 复制代码 代码如下: var arr = [1,2,3,4,5,6,7,8,9,10]; var even = function{ if(typeof item !== "number") return false; return !; }; console.log; 结果: [2, 4, 6, 8, 10] 这样消除循环之后,更贴近于数学的归纳定义,显得更自然。同样地,再看一下ffold函数: 复制代码 代码如下: var arr = [1,2,3,4,5,6,7,8,9,10]; var plus = function{ return a+b; }; console.log; 结果: 58 其他函数以同样的方法即可。这样就感觉更functional 了,但能不能再与数学定义更加接近呢?下一次再尝试。 ==========2013.1.8 更新================== 上面说到了那些写法能否与数学定义更加接近,下面就尝试一下使用链表。先给出一个定义: 复制代码 代码如下: var node = function(){ this.data = 0; this.tail = null; }; 再初始化一个链表: 复制代码 代码如下: var n1 = new node,n3 = new node,n5 = new node(); n1.data=1,n1.tail=n2; n2.data=2,n2.tail=n3; n3.data=3,n3.tail=n4; n4.data=4,n4.tail=n5; n5.data=5,n5.tail=null; fold链表版本: 复制代码 代码如下: function lfold{ if return b; else return callback(head.data,arguments.callee); } 输出结果: 18 按照之前的定义,一个集合要么是空集,要么是一个“头”与一个“尾”组成的数对。每一次调用函数时,分解为head和tail,直到集合为空(写完上面的lfold函数真心感觉太完美了,简直就是定义,要是程序都长这样,注释都不需要了,真是一种享受)。这样子算是最接近数学定义的表示了。因为javascript不支持很多函数式语言的match,所以不能“自动”分解,也就不能直接表示归纳定义。 javascript除了以上的一些东西,还可以实现函数式里面的partial,dojo框架里面的hitch就做到了这一功能,这也是函数式贴近数学的另外一个明显的例子。我将在下一篇博客中讨论。

前言

javascript设计模式之对象工厂函数与构造函数详解,javascript设计模式

下面通过文字详解加代码分析的方式给大家分享下javascript设计模式之对象工厂函数与构造函数的相关知识。

概述使用对象字面量,或者向空对象中动态地添加新成员,是最简单易用的对象创建方法。然而,除了这两种常用的对象创建方式,JavaScript还提供了其他方法创建对象。1).使用工厂函数创建对象我们可以编写一个函数,此函数的功能就是创建对象,可将其.

概述

使用对象字面量,或者向空对象中动态地添加新成员,是最简单易用的对象创建方法。
然而,除了这两种常用的对象创建方式,JavaScript还提供了其他方法创建对象。
1).使用工厂函数创建对象

我们可以编写一个函数,此函数的功能就是创建对象,可将其称为“对象工厂方法”。

复制代码 代码如下:
//工厂函数    
 function createPerson(name, age, job) {        
 var o = new Object();        
 o.name = name;        
 o.age = age;        
 o.job = job;        
 o.sayName = function () {            
 console.info(this.name);        
 };        
 return o;      } //使用工厂函数创建对象    
 var person1 = createPerson('张三', 29, '软件工程师');    
 var person2 = createPerson('李四', 40, '医生');

2).定义对象构造函数

  a).对象构造函数首字母大写
  b).内部使用this关键字给对象添加成员
  c).使用new关键字调用对象构造函数

复制代码 代码如下:
//定义对象“构造”函数     
function Person(name, age, job) {
this.name = name;        
 this.age = age;         
this.job = job;         
this.sayName = function () {            

  console.info(this.name);         
};     
} //使用new调用对象构造函数创建对象    
 var p1 = new Person('张三', 29, '软件工程师');     

var p2 = new Person('李四', 40, '医生');

以普通方式调用的“构造函数”

构造函数其实也是一个函数,不同之处在于调用它时必须要加一个“new”关键字,如果不加这个关键字,则对它的调用被认为是普通函数调用。

复制代码 代码如下:
 //作为普通函数调用的构造函数,通过this添加的属性,
//成为了window对象的属性与方法。
console.info(window.name);//张三
console.info(window.age); //29
console.info(window.job); //软件工程师

对象构造函数长得这个样:

复制代码 代码如下:
function Person (name) {
this.name = name;
 this.say = function () {
 return "I am " + this.name;
  };
}

实际上是这样(示意):

复制代码 代码如下:
function Person (name) {
// var this = {};
 this.name = name;
 this.say = function () {
return "I am " + this.name;
 };
    // return this;
}

构造函数完成的工作

**1. 创建一个新的对象

  1. 让构造函数的this引用这一新创建的对象
  2. 执行构造函数中的代码,这些代码通常完成向新对象添加属性的工作
  3. 向外界返回新创建的对象引用。
    **对象构造函数与对象工厂方法的区别

**1. 对象构造函数中没有显式的对象创建代码

  1. 新对象应具备的属性与方法是通过this引用添加的.
  2. 对象构造函数中没有return语句
    ** 通常会把对象构造函数的首字母设置为大写的,以区别于普通函数。
    对象的constructor属性

a).使用对象工厂函数创建对象,每个对象的constructor属性引用Object()

 复制代码 代码如下:
var person = createPerson('张三', 29, '软件工程师');
 //使用工厂方法创建对象,

其constructor属性引用Object()函数
console.info(person1.constructor === Object); 

//true

b).使用对象构造函数创建对象,每个对象的constructor属性引用这个构造函数

复制代码 代码如下:
var p = new Person('张三', 29, '软件工程师');
//使用对象构造函数创建对象,
//每个对象的constructor属性,引用这个构造函数
console.info(p.constructor === Person);
 //true如何避免“忘记”new?可以使用arguments.callee解决这个问题     
//了解arguments.callee的作用    
function TestArgumentsCallee()
 {         
console.info(this);         
console.info(this instanceof TestArgumentsCallee);        
 console.info(this instanceof arguments.callee);    
 };     
TestArgumentsCallee(); //window                                         

//false                                         
//false     
new TestArgumentsCallee(); 
//TestArgumentsCallee             
//true                                             

  //true

于是,可以直接用arguments.callee

复制代码 代码如下:
 //避免忘记new    
 function MyObject(value)
{        
 if (!(this instanceof arguments.callee))

{            
 //如果调用者忘记加上new了,就加上new再调用一次             

return new MyObject(value);        
 }        
 this.prop = value;    
 }     
//测试     
var obj1 = new MyObject(100);    
 console.info(obj1.prop);//100    
 var obj2 = MyObject(200);       
console.info(obj2.prop); //200

以上内容就是javascript设计模式之对象工厂函数与构造函数详解,希望大家喜欢。

下面通过文字详解加代码分析的方式给大家分享下javascript设计模式之对...

三种检测对象的类方式: instanceof、constructor 、构造函数名字

 

 

我在上一篇【javascript基础】基本概念中介绍了javascript的一些基本概念,多谢大家的阅读和意见,自己写的东西可以被大家阅读,真心高兴,刚开始发布的时候我一直盯着阅读人数,虽然知道大家可能就是点开一下而已,但是还是给我一些继续写下去的信心。那今天写一些关于javascript函数的一些知识,帮助大家熟悉或者复习一些函数的基本知识。

用法如下:

 

 

PS:最近jQuery源码交流群( 239147101)加了不少热新人,希望大家还是以学习为主,尽量少灌水,给大家一个好的提升自己的环境。

1)instanceof

 

 

函数

console.log([1,2,3] instanceof Array);

 

true

函数在任何一种编程语言中都是一个很重要的结构或者组成部分,编程中的复杂结构和功能都会有函数的参与。javascript中的函数是一个对象,函数对象时Function类型的实例,由于Function类型是一个引用类型,那么函数可以拥有自己的方法和属性,同时也因为函数是一个对象,那么函数名是一个指向函数对象的指针,可以被赋值。下面详细介绍函数的各个部分。

 

 

console.log([1,2,3] instanceof Object);

创建函数

true

 

尽管构造函数是原型的唯一标识,instanceof运算符的右操作数是构造函数,instanceof实际计算过程中检测的是对象的继承关系,而不是检测的创建对象时的构造函数,只是使用了构造函数作为中介

函数的创建有三种方式,分别为使用Function的构造函数、函数声明、函数表达式,下面分别介绍这三种方法。

 

 

 

Function构造函数

 

 

当然也可以使用isPrototypeOf 来判断一个对象是否存在于另一对象的原型链中,此时不使用构造函数作为中介

这种方式是直接new出来一个Function 实例,通过使用Function的构造函数进行创建函数。Function构造函数可以接收任意多个参数,但是最后一个参数会被认为是函数体,前面的所以参数被当做被创建出来的函数的参数。

 

 

var a1 = new Array();

var test = new Function("a","b","return a + b");//参数a和b,函数体return a + b

console.log(Array.prototype.isPrototypeOf(a1));

console.log(test(1,2));//3

true

我们可以看出比较的麻烦,并且《javascript高级程序设计》也不推荐我们使用这种方式,主要是因为浏览器要解析常规的javascript代码之外,还要解析传入的参数字符串,这个类似eval()的解释,影响性能。

 

 

console.log(Array.prototype.isPrototypeOf([1,2,3]));

函数表达式

true

 

注意:多个执行上下文时(例如存在不同框架时)instanceof使用有限制

这种方式是创建的常见方式之一,具体请看

 

 

 

var test = function(a,b){

 

  return a + b;  

2)constructor

}

 

console.log(test(1,2));

每个javascript函数都可以用作构造函数,调用构造函数需要使用prototype属性,因而每个javascript函数会自动拥有prototype属性,这个属性值是一个对象,这个对象包含一个contructor属性,constructor属性值是一个函数对象。

上面的代码就是创建一个函数,使用test()进行调用。其实,上面的代码是先创建了一个匿名的函数,之后把这个匿名的函数赋值给test变量。每个函数有一个name属性,这个属性不是ECMA标准的一部分,但是许多地方可以使用它。我们可以给上面的函数起一个名字,具体下面代码

 

 

即对于函数var F = function(){}; F.prototype.constructor===F

复制代码

 

//函数的名字newName

关系图如下:

var test = function newName(a,b){

 

  return a + b;  

 

}

 

console.log(test.name);//newName

 

 

 

//匿名函数

eg:

var nTest = function (a,b){

 

  return a + b;  

复制代码

}

var F= function(){};

console.log(nTest.name);//undefined

var p = F.prototype;

复制代码

var c = p.constructor;

这个属性在后面详细解释吧。

console.log(p);

 

console.log(c);

函数声明

console.log(c===F);

 

 

这种方式和C语言中的很类似,这种是最常见的一种创建函数的方法。是通过关键字function直接声明,请看

Object {}

 

function (){}

function test(a,b){

true

  return a + b;  

复制代码

}

因而对象继承的constructor均指代他们的构造函数

console.log(test(1,2));//3

 

console.log(test.name);//test

eg:

区别

 

 

 

以上介绍了三个创建函数的方式,现在介绍三种的区别,确切的说是后两种的区别,因为Function不推荐使用,性能是一大原因。区别就是使用函数声明这种方式会使函数的声明提前,类似前面我们提到的变量申明的提前。也就是说,使用函数申明方式,我们可以将函数的声明放在调用函数代码的后面,因为解析器会在代码执行之前将函数的声明提升,提到源代码树的顶部,而函数表达式方式则会报错,具体请看

 

 

var o= new F();

复制代码

console.log(o.constructor===F);

//调用函数

 

console.log(test(1,2));//3

//输出 

//创建函数(函数申明方式)

true

function test(a,b){

 

  return a + b;  

 

}

var a = new Array();

//上面的函数相等于

console.log(a.constructor===Array);

//创建函数(函数申明方式)

//输出

//function test(a,b){

true

//  return a + b;  

 

//}

 

本文由必威发布于必威-运维,转载请注明出处:要么是一个数与一个集合组成的数对从定义可以

相关阅读