在JavaScript中yield实用简洁实现方式

 刚才忽然灵机一动,迭代器我们很少会真的直接傻乎乎的next去遍历的,那为什么一定要实现这个傻乎乎的next呢?直接实现each,这样,这样反过来,Yeah,一通百通,不一会儿就写出了第一个超简洁版本:

代码

 


function yieldHost(yieldFunction)
{
return function (processer)
{
var yield = function (result)
{
processer(result)
};

yieldFunction(yield);

};
}

 

 

思路一换,代码真简洁。

先附上例子,然后来谈原理。

首先我们需要一个函数来进行枚举,像这样:

 


function fun(yield)
{

for (var i = 0; i < 100; i++)
yield(i);

}

 

或是这样:

 


function fun(yield)
{

yield(1);
yield(2);
yield(3);

}

 

由于实现方式与C#的不同,所以在循环体内也不用什么yield break或是yield continue这样的语法,直接break或是continue就好了。

然后是实际的运用,yieldHost函数可以将上面的符合要求的fun函数转换为一个枚举器:

 


var enumerator = yieldHost(fun);

 

这个枚举器其实也是一个函数,像jQuery的each函数一样,接收一个处理函数来处理枚举:

 


enumerator(function (item)
{
window.alert(item);
});

 

接下来谈谈原理。

对于传统的枚举器来说,我们会认为枚举器应该在每次调用返回一个值,这就是next方法,但就像陈子瀚说的,这需要在yield的时候把函数停住,虽然可以实现,但真的很麻烦。

但!事实上我发现,大多数时候,我们都是用foreach这样的语法来访问枚举器的。这样一来就给了我一个非常讨巧的办法,不实现next方法,而是实现each方法。

each方法和next的方法的区别在哪里呢?熟悉jQuery的朋友就会知道,each方法其实可以视为将next倒过来,不是返回枚举值,而是接收一个函数,把枚举值当作参数传进去。

正是这一倒,所有问题都迎刃而解了。我们没有必要去暂停一个函数的执行,只需要将处理枚举值的逻辑注到这个函数里面去就完了。所以事实上这里的yieldHost就是完成了一个倒装的工作,把enumerator接收的那个函数(也就是window.alert( item ),注到了枚举函数中(即fun)。最终执行的效果就像是这样:

 


function fun(yield)
{

window.alert(1);
window.alert(2);
window.alert(3);

}

 

所以就诞生了这个超简洁的实现。

有了这个超简洁的实现,下一步就是实现像jQuery的each方法一样的return true代表break和return false代表continue的功能了,只有具备了这样的功能,才能处理无穷集,或是实现TakeWhile之类的功能。

老实说我对JavaScript的研究并不透彻,只想到了一个使用异常打断的办法,这就是第二个版本的yieldHost:

代码

 


function yieldHost(yieldFunction)
{

var exception = Math.random();

return function (processer)
{
try
{
yieldFunction(function (result)
{
if (processer(result))
throw exception;
});
}
catch (e)
{
if (e !== exception)
throw e;
}

};
}

 

 

显然这并不完美,但我实在想不出更好的办法。

接下来在这个基础上实现Select、Where什么,其实是非常简单的事情,给出一个我的Select的实现:

代码

 


function Select(enumerator, selector)
{
return function (fun)
{
enumerator(function (item)
{
return fun(selector(item));
});
}
}

 

 

至于,这个Select怎么修改成连写的版本,即:

enumerator.Select( selector )( processor );

我觉得这对JavaScript而言真不是一件很难的事情啊。。。。

只是,过早的引入语法友好,会把JavaScript变得很复杂难看。所以,这个留给大家去玩吧。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索函数
, 方法
, function
, yield
, 一个
, 简洁
, enumerate函数
, 简洁函数
, $(selector).each()
简洁方法
javascript yield、javascript yield用法、lua yield 实现、最简洁实用的网址导航、简洁实用装修,以便于您获取更多的相关知识。

时间: 2024-12-31 09:33:43

在JavaScript中yield实用简洁实现方式的相关文章

JavaScript中yield实用简洁实现方式_javascript技巧

刚才忽然灵机一动,迭代器我们很少会真的直接傻乎乎的next去遍历的,那为什么一定要实现这个傻乎乎的next呢?直接实现each,这样,这样反过来,Yeah,一通百通,不一会儿就写出了第一个超简洁版本: 复制代码 代码如下: function yieldHost(yieldFunction) { return function (processer) { var yield = function (result) { processer(result) }; yieldFunction(yield

探讨JavaScript中声明全局变量三种方式的异同

     这篇文章主要介绍了JavaScript中声明全局变量三种方式的异同.变量及变量声明是一门语言最基本的概念,初学者都会很快掌握.需要的朋友可以过来参考下,希望对大家有所帮助 变量及变量声明是一门语言最基本的概念,初学者都会很快掌握.JavaScript中声明变量也是如此,很简单var(关键字)+变量名(标识符).   方式1   var test; var test = 5;需注意的是该句不能包含在function内,否则是局部变量.这是第一种方式声明全局变量.   方式2   test

javascript中创建对象的几种方式

原文:javascript中创建对象的几种方式 javascript中提供了通过Object构造函数或对象字面量方式来创建单个的对象,当我们想要创建很多对象的时候,简单的通过这两种方法就会产生大量的重复.在此,我总结了几种创建对象的模式.本文是在我阅读<javascript高级程序设计>后总结而来. 1.工厂模式 这种模式通过用函数来减少代码重复,利用函数的参数作为接口,与对象的属性与方法对接. function createfactory(name,age){ var obj = new O

Javascript中的几种继承方式对比分析_基础知识

开篇从'严格'意义上说,javascript并不是一门真正的面向对象语言.这种说法原因一般都是觉得javascript作为一门弱类型语言与类似java或c#之类的强型语言的继承方式有很大的区别,因而默认它就是非主流的面向对象方式,甚至竟有很多书将其描述为'非完全面向对象'语言.其实个人觉得,什么方式并不重要,重要的是是否具有面向对象的思想,说javascript不是面向对象语言的,往往都可能没有深入研究过javascript的继承方式,故特撰此文以供交流. 为何需要利用javascript实现继

详细分析Javascript中创建对象的四种方式_javascript技巧

前言 使用Javascript创建对象的方式有很多,现在就来列举一下其中的四种方式,并且罗列出了每种方式的优缺点,可以让大家进行选择使用,下面来看看. 工厂模式 function createPerson(name, age){ var obj = new Object(); obj.name = name; obj.age = age; return obj; //一定要返回,否则打印undefined:undefined } var person1 = new createPerson('Y

探讨JavaScript中声明全局变量三种方式的异同_javascript技巧

变量及变量声明是一门语言最基本的概念,初学者都会很快掌握.JavaScript中声明变量也是如此,很简单var(关键字)+变量名(标识符). 方式1 var test;var test = 5;需注意的是该句不能包含在function内,否则是局部变量.这是第一种方式声明全局变量. 方式2 test = 5;没有使用var,直接给标识符test赋值,这样会隐式的声明了全局变量test.即使该语句是在一个function内,当该function被执行后test变成了全局变量. 方式3 window

实现JavaScript中继承的三种方式_js面向对象

一.原型链继承 在原型链继承方面,JavaScript与java.c#等语言类似,仅允许单父类继承.prototype继承的基本方式如下: 复制代码 代码如下: function Parent(){} function Child(){} Child.prototype = new Parent(); 通过对象Child的prototype属性指向父对象Parent的实例,使Child对象实例能通过原型链访问到父对象构造所定义的属性.方法等. 构造通过原型链链接了父级对象,是否就意味着完成了对象

Javascript中的几种继承方式比较

原文地址 开篇 从'严格'意义上说,javascript并不是一门真正的面向对象语言.这种说法原因一般都是觉得javascript作为一门弱类型语言与类似java或c#之类的强型语言的继承方式有很大的区别,因而默认它就是非主流的面向对象方式,甚至竟有很多书将其描述为'非完全面向对象'语言.其实个人觉得,什么方式并不重要,重要的是是否具有面向对象的思想,说javascript不是面向对象语言的,往往都可能没有深入研究过javascript的继承方式,故特撰此文以供交流. 为何需要利用javascr

在JavaScript中实现类的方式探讨_javascript技巧

在 javascript 中有很多方式来创建对象,所以创建对象的方式使用起来非常灵活.那么,到底哪一种方式是最恰当的对象创建方式呢?构造模式,原型模式还是对象原意模式(Object literal)呢? 但这些模式具体是怎么回事呢? 在开始讲解之前,让我们先清楚地介绍一下关于 javascript 基本知识. 有没有可能在 javascript 中实现面向对象编程的方式呢? 答案是可能的,javascript 是可以创建对象的!这种对象可以包含数据及能够操作数据的方法,甚至可以包含其他对象.它没