1.jQuery的链式操作是如何实现的?
2.为什么要用链式操作?
大家认为这两个问题哪个好回答一点呢?
链式操作
原理相信百度一下一大把,实际上链式操作仅仅是通过对象上的方法最后
return this
把对象再返回回来,对象当然可以继续调用方法啦,所以就可以链式操作了。那么,简单实现一个:
//定义一个JS类
function Demo() {
}
//扩展它的prototype
Demo.prototype ={
setName:function (name) {
this.name = name;
return this;
},
getName:function () {
return this.name;
},
setAge:function (age) {
this.age = age;
return this;
}
};
////工厂函数
function D() {
return new Demo();
}
//去实现可链式的调用
D().setName("CJ").setAge(18).setName();
但……为什么要用呢?
一般的解释:
节省代码量,代码看起来更优雅。
例如如果没有链式,那么你可能需要这样写代码:
document.getElementById("ele").dosomething();
document.getElementById("ele").dootherthing();
这个代码中调用了两次document.getElementById来获取DOM树的元素,这样消耗比较大,而且要写两行,而链式只要写一行,节省了代码……
但我们也可以用缓存元素啊。比如:
var ele = document.getElementById("ele");
ele.dosomething();
ele.dootherthing();
而且两行并没有比一行多多少代码,甚至相应的封装反而使得代码更多了。
最糟糕的是所有对象的方法返回的都是对象本身,也就是说没有返回值,这不一定在任何环境下都适合。
举个例子,我们想弄一个超大整数BigInteger(意思是如果用Javascript的Number保存可能会溢出的整数),顺便扩展他的运算方法,会适合用链式操作么?
例如运算31415926535 * 4 - 271828182,如果设计成链式风格的方法可能会是这样的:
var result = (new BigInteger("31415926535")).multiply(new BigInteger("4")).subtract(new BigInteger("271828182")).val();
console.log("result == " + result);
这看起来似乎也很优雅,但是如果我们想要中间的结果怎么办呢?或许会写成这样:
var bigInteger = new BigInteger("31415926535");
var result1 = bigInteger.multiply(new BigInteger("4")).val();
var result2 = bigInteger.subtract(new BigInteger("271828182")).val();
console.log("result1 == " + result1 + ", result2 == " + result2);
这似乎一点也不优雅了,和不用链式操作没啥不同嘛!
那么如果要求是原来的BigInteger不能改变呢?好吧,链式操作似乎不能满足这个需求了。
那么到底为什么要用链式操作呢?
为了更好的异步体验
Javascript是无阻塞语言,所以他不是没阻塞,而是不能阻塞,所以他需要通过事件来驱动,异步来完成一些本需要阻塞进程的操作。
但是异步编程是一种令人疯狂的东西……运行时候是分离的倒不要紧,但是编写代码时候也是分离的就……
常见的异步编程模型有哪些呢?
•回调函数
所谓的回调函数,意指先在系统的某个地方对函数进行注册,让系统知道这个函数的存在,然后在以后,当某个事件发生时,再调用这个函数对事件进行响应。
function f(num, callback){
if(numalert("调用低层函数处理!");
alert("分数不能为负,输入错误!");
}else if(num==0){
alert("调用低层函数处理!");
alert("该学生可能未参加考试!");
}else{
alert("调用高层函数处理!");
setTimeout(function(){callback();}, 1000);
}
}
这里callback则是回调函数。可以发现只有当num为非负数时候callback才会调用。
但是问题,如果我们不看函数内部,我们并不知道callback会几时调用,在什么情况下调用,代码间产生了一定耦合,流程上也会产生一定的混乱。
虽然回调函数是一种简单而易于部署的实现异步的方法,但从编程体验来说它却不够好。
•事件监听
也就是采用事件驱动,执行顺序取决于事件顺序。
function EventTarget(){
this.handlers = {};
}
EventTarget.prototype = {
constructor: EventTarget,
addHandler: function(type, handler){
this.handlers[type] = [];
},
fire: function(){
if(!event.target){
event.target = this;
}
if(this.handlers[event.type instanceof Array]){
var handlers = this.handlers[event.type];
for(var i = 0, len = handlers.length, i handlers[i](event);
}
}
},
removeHandler: function(type, handler){
if(this.handlers[type] instanceof Array){
var handlers = this.handlers[type];
for(var i = 0, le = handlers.length; i if(handlers[i] === handler){
break;
}
}
handlers.splice(i, 1);
}
}
};
上面是《JavaScript高级程序设计》中的自定义事件实现。于是我们就可以通过addHandler来绑定事件处理函数,用fire来触发事件,用removeHandler来删除事件处理函数。
虽然通过事件解耦了,但流程顺序更加混乱了。
•链式异步
个人觉得链式操作最值得称赞的还是其解决了异步编程模型的执行流程不清晰的问题。jQuery中$(document).ready就非常好的阐释了这一理念。DOMCotentLoaded是一个事件,在DOM并未加载前,jQuery的大部分操作都不会奏效,但jQuery的设计者并没有把他当成事件一样来处理,而是转成一种“选其对象,对其操作”的思路。$选择了document对象,ready是其方法进行操作。这样子流程问题就非常清晰了,在链条越后位置的方法就越后执行。
(function(){
var isReady=false; //判断onDOMReady方法是否已经被执行过
var readyList= [];//把需要执行的方法先暂存在这个数组里
var timer;//定时器句柄
ready=function(fn) {
if (isReady )
fn.call( document);
else
readyList.push( function() { return fn.call(this);});
return this;
}
var onDOMReady=function(){
for(var i=0;i
}
readyList = null;
}
var bindReady = function(evt){
if(isReady) return;
isReady=true;
onDOMReady.call(window);
if(document.removeEventListener){
document.removeEventListener("DOMContentLoaded", bindReady, false);
}else if(document.attachEvent){
document.detachEvent("onreadystatechange", bindReady);
if(window == window.top){
clearInterval(timer);
timer = null;
}
}
};
if(document.addEventListener){
document.addEventListener("DOMContentLoaded", bindReady, false);
}else if(document.attachEvent){
document.attachEvent("onreadystatechange", function(){
if((/loaded|complete/).test(document.readyState))
bindReady();
});
if(window == window.top){
timer = setInterval(function(){
try{
isReady||document.documentElement.doScroll('left');//在IE下用能否执行doScroll判断dom是否加载完毕
}catch(e){
return;
}
bindReady();
},5);
}
}
})();
上面的代码不能用$(document).ready,而应该是window.ready。
•Promise
CommonJS中的异步编程模型也延续了这一想法,每一个异步任务返回一个Promise对象,该对象有一个then方法,允许指定回调函数。
所以我们可以这样写:
f1().then(f2).then(f3);
这种方法我们无需太过关注实现,也不太需要理解异步,只要懂得通过函数选对象,通过then进行操作,就能进行异步编程。

javaandjavascriptaredistinctlanguages:javaisusedforenterpriseandmobileapps,while javascriptifforInteractiveWebpages.1)JavaisComcompoppored,statieldinglationallyTypted,statilly tater astrunsonjvm.2)

JavaScript核心数据类型在浏览器和Node.js中一致,但处理方式和额外类型有所不同。1)全局对象在浏览器中为window,在Node.js中为global。2)Node.js独有Buffer对象,用于处理二进制数据。3)性能和时间处理在两者间也有差异,需根据环境调整代码。

JavaScriptusestwotypesofcomments:single-line(//)andmulti-line(//).1)Use//forquicknotesorsingle-lineexplanations.2)Use//forlongerexplanationsorcommentingoutblocksofcode.Commentsshouldexplainthe'why',notthe'what',andbeplacedabovetherelevantcodeforclari

Python和JavaScript的主要区别在于类型系统和应用场景。1.Python使用动态类型,适合科学计算和数据分析。2.JavaScript采用弱类型,广泛用于前端和全栈开发。两者在异步编程和性能优化上各有优势,选择时应根据项目需求决定。

选择Python还是JavaScript取决于项目类型:1)数据科学和自动化任务选择Python;2)前端和全栈开发选择JavaScript。Python因其在数据处理和自动化方面的强大库而备受青睐,而JavaScript则因其在网页交互和全栈开发中的优势而不可或缺。

Python和JavaScript各有优势,选择取决于项目需求和个人偏好。1.Python易学,语法简洁,适用于数据科学和后端开发,但执行速度较慢。2.JavaScript在前端开发中无处不在,异步编程能力强,Node.js使其适用于全栈开发,但语法可能复杂且易出错。

javascriptisnotbuiltoncorc; saninterpretedlanguagethatrunsonenginesoftenwritteninc.1)javascriptwasdesignedAsalightweight,解释edganguageforwebbrowsers.2)Enginesevolvedfromsimpleterterterpretpreterterterpretertestojitcompilerers,典型地提示。

JavaScript可用于前端和后端开发。前端通过DOM操作增强用户体验,后端通过Node.js处理服务器任务。1.前端示例:改变网页文本内容。2.后端示例:创建Node.js服务器。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

MinGW - 适用于 Windows 的极简 GNU
这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

SublimeText3 Linux新版
SublimeText3 Linux最新版

EditPlus 中文破解版
体积小,语法高亮,不支持代码提示功能

DVWA
Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中