第十八章 高级技巧
1.高级函数
1.1 作用域安全的构造函数
①直接调用构造函数而不适用new操作符时,由于this对象的晚绑定,它将映射在全局对象window上,导致对象属性错误增加到window。
复制代码 代码如下:
function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
}
Var person = Person("Jay",29,"singer"); //属性增加到window对象上。
②作用域安全构造函数
复制代码 代码如下:
function Person(name,age,job){
if(this instanceof Person){
this.name = name;
this.age = age;
}else{
return new Person(name,age);
}
}
③上述作用域安全的构造函数,如果使用构造函数窃取模式的继承且不使用原型链,那么这个继承很可能被破坏。
□如果构造函数窃取结合使用原型链或者寄生式组合则可以解决这个问题。
复制代码 代码如下:
function Polygon(side){
if(this instanceof Polygon){
this.sides = sides;
this.getArea = function{return 0;};
}else{
return new Polygon(sides);
}
}
function Rectangle(width,height){
Polygon.call(this,2);
this.width = width;
this.height = height;
this.getArea = function(){
return this.width * this.height;
};
}
Rectangle.prototype = new Polygon();
var rect = new Rectangle(5,10);
alert(rect.sides); //2
1.2 惰性载入函数
①惰性载入表示函数执行的分支仅会发生一次:既第一次调用的时候。在第一次调用的过程中,该函数会被覆盖为另一个按合适方式执行的函数,这样任何对原函数的调用都不用再经过执行的分支了。
■优点:
□要执行的适当代码只有当实际调用函数时才进行。
□尽管第一次调用该函数会因额外的第二个函数调用而稍微慢点,但后续的调用都会很快,因避免了多重条件。
复制代码 代码如下:
function create XHR(){
if(typeof XMLHttp Request != "undefined"){
createXHR = function(){
return new XMLHttpRequest();
};
}else if(typeof ActiveXObject != "undefined"){
createXHR = function(){
if(typeof arguments.callee.activeXString != "string"){
var versions = ["MSXML2.XMLHttp.6.0","MSXML2.XMLHttp.3.0","MSXML2.XMLHttp"];
for(vai I = 0, len = versions.length; I < len; i++){
try{
Var xhr = new ActiveXObject(version[i]);
Arguments.callee.activeXString = version[i];
Return xhr;
}catch(ex){
//skip
}
}
}
return new ActiveXObject(arguments.callee.activeXString);
};
}else{
createXHR = function(){
throw new Error("No XHR Object available.");
};
}
return createXHR();
}
1.3 函数绑定
①函数绑定要创建一个函数,可以在特定环境中以指定参数调用另一个函数。
②一个简单的bind()函数接受一个函数和一个环境,并返回一个在给定环境中调用给定函数的函数,并且将所有参数原封不动传递过去。
复制代码 代码如下:
function bind(fn, context){
return function(){
return fn.apply(context, arguments);
};
}
③被绑定函数与普通函数相比有更多的开销——它们需要更多内存,同时也因为多重函数调用而稍微慢一点——所以最好只在必要时使用。
1.4 函数柯里化
定义:用于创建已经设置好了一个或多个参数的函数。函数柯里化的基本方法和函数绑定是一样的:使用一个闭包返回一个函数。两者的区别在于,当函数被调用时,返回函数还需要设置一些传入的参数。
复制代码 代码如下:
function bind(fn, context){
var args = Array.prototype.slice.call(arguments, 2);
return function(){
var innerArgs = Array.prototype.slice.call(arguments);
var finalArgs = args.concat(innerArgs);
return fn.apply(context,finalArgs);
};
}
2.高级定时器
①JavaScript是单线程程序,定时器是在间隔时间后将代码添加到列队。
②执行完一套代码后,JavaScript进程返回一段很短的时间,这样页面上的其他处理就可以进行了。
2.1 重复的定时器
①setInterval()仅当没有该定时器的任何其他代码实例时,才将定时器代码添加到队列中。
□某些间隔会被跳过。
□多个定时器代码执行之间的间隔可能会比预期小。
②避免setInterval()的两个缺点,使用链式setTimeout()调用:
复制代码 代码如下:
setTimeout(function(){
//处理
if(condition){
setTimeout(arguments.callee, interval);
}
},interval);
2.2 Yielding Processes
①JavaScript长时间运行脚本制约:如代码运行超过特定的时间或特定的语句数量就不会让它继续执行。
②当某个函数要花200ms以上的事件完成,最好分割为一系列可以使用定时器的小任务。
③数组分块技术:为要处理的项目创建一个队列,然后使用定时器取出下一个要处理的项目进行处理,接着再设置另一个定时器。
复制代码 代码如下:
function chunk(array, process, context){
setTimeout(function(){
var item = array.shift();
process.call(context,item);
if(array.length>0){
setTimeout(arguments.callee, 100);
}
}
}
2.3 函数节流
①DOM操作比起非DOM交互需要更多内存和CPU时间。连续尝试进行过多的DOM相关操作可能会导致浏览器挂起,有时甚至崩溃。
②函数节流思想:某些代码不可以在没有间断的情况连续重复执行。
□示例
复制代码 代码如下:
var processor = {
timeoutId : null,
//实际进行处理的方法
performProcessing : function(){
//实际执行的方法
},
//初始处理调用的方法
process : function(){
clearTimeout(this.timeoutId);
var that = this;
this.timeoutId = setTimeout(function(){
that.performProcessing();
},100);
}
};
//尝试开始执行
Processor.process();
□简化模式
function throttle(method,context){
clearTimeout(mehtod.tId);
mehtod.tId = setTimeout(function(){
method.call(context);
},100);
}
3.自定义事件
①事件是一种叫做观察者的设计模式,这是一种创建松散耦合代码的技术。
□对象可以发布事件,用来表示该对象声明周期中某个有趣的时刻到了。
□其他对象可以观察该对象,等待有趣的时刻到来并通过运行代码来响应。
②观察者模式由两类对象组成:主体和观察者。
□主体负责发布事件,同时观察者通过订阅这些事件来观察主体。
□主体并不知道观察者的任何事情,它可以独立自存在并正常运作即使观察者不在。
③自定义事件:创建一个管理事件的对象,让其他对象监听那些事件。
复制代码 代码如下:
function EventTarget(){
this.handlers = {};
}
EventTarget.prototype = {
constructor : EventTarget,
addHandler : function(type,handler){
if(typeof this.handlers[type] == "undefined"){
this.handlers[type] = [];
}
this.handlers[type].push(handler);
},
fire : function(event){
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<len; i++){
handlers[i](event);
}
}
},
removeHandler : function(type, handler){
if(this.handlers[type] instanceof Array){
var handlers = this.handlers[type];
for(var i=0,len=handlers.length; i<len; i++){
if(handlers[i] === handler){
break;
}
}
Handlers.splice(i,1);
}
};
④使用EventTarget类型的自定义事件可以如下使用:
复制代码 代码如下:
function handleMessage(event){
alert("message received:" + event.message);
}
//创建一个新对象
var target = new EventTarget();
//添加一个事件处理程序
target.addHandler("message",handleMessage);
//触发事件
target.fire({type:"message",message:"hello world!"});
//删除事件处理程序
target.removeHandler("message",handleMessage);
⑤使用实例
复制代码 代码如下:
function Person(name,age){
eventTarget.call(this);
this.name = name;
this.age = age;
}
inheritPrototype(Person, EventTarget);
Person.prototype.say = function(message){
this.fire({type:"message", message:message});
};
function handleMessage(event){
alert(event.target.name + "says: " + event.message);
}
//创建新person
var person = new Person("Nicholas",29);
//添加一个事件处理程序
Person.addHandler("message",handleMessage);
//在该对象上调用1个方法,它触发消息事件
person.say("Hi there");
4.拖放
功能:①拖放②添加了自定义事件
复制代码 代码如下:
var DragDrop = function(){
var dragdrop = new EventTarget();
var dragging = null;
var diffX = 0;
var diffY = 0;
function handleEvent(event){
//获取事件和对象
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
//确定事件类型
switch(event.type){
case "mousedown" :
if(target.className.indexOf("draggable")>-1){
dragging = target;
diffX = event.clientX - target.offsetLeft;
diffY = event.clientY - target.offsetTop;
dragdorp.fire(
{
type:"dragstart",
target : dragging,
x : event.clientX,
y : event.clientY
}
);
break;
case "mousemove" :
if(dragging !== null){
//获取事件
event = EventUtil.getEvent(event);
//指定位置
dragging.style.left = (event.clientX - diffX) + "px";
dragging.style.top = (event.clientY - diffY) + "px";
//触发自定义事件
dragdrop.fire(
{
type : "drag",
target : dargging,
x : event.clientX,
y : event.clientY
}
);
}
break;
case "mouseup" :
dargdorp.fire(
{
type : "dragend",
target : dragging,
x : event.clientX,
y : event.clientY
}
);
dragging = null;
break;
}
}
//公共接口
dragdrop.enable = function() {
EventUtil.addHandler(document, "mousedown", handleEvent);
EventUtil.addHandler(document, "mousemove", handleEvent);
EventUtil.addHandler(document, "mouseup", handleEvent);
};
dragdrop.disable = function(){
EventUtil.removeHandler(document, "mousedown", handleEvent);
EventUtil.removeHandler(document, "mousemove", handleEvent);
EventUtil.removeHandler(document, "mouseup", handleEvent);
};
return dragdrop;
}();
相关推荐:
WP原创:打造属于你的独特网站,从这里开始!,一个网站推广一个月需要多少钱
用AI优化文章,轻松提升内容质量与创作效率
ChatGPT的梯子:突破网络壁垒,畅享智能对话的全新体验,ai的音标1001ai的音标
SEO针对中小企业的增长潜力:如何通过精准优化抢占市场先机,网络推广和营销就选y火10星评价
ChatGPT美区要梯子吗?轻松畅享全球智能聊天体验,ai音位
ChatGPT页面空白不乏登录:让你秒变职场高手与生活智囊,百度ai 腾讯ai
ChatGPT免费版的限制:你需要了解的5大制约因素,Ai分解模型
WPS改写-轻松提升文档创作效率的秘密武器,推广网站的优势
360ai答题-赋能教育,开启智能学习新纪元,ai 果汁
什么是seo方法,何为seo ,ai写作神器源码是什么
seo需要保持什么心态,seo的要求 ,ai83562
怎么识别是AI写的文章
SEO优化排名:让您的网站在搜索引擎中脱颖而出,我ai 达瓦仓决
优化整站,让网站飞速增长,打造行业竞争力,广东网站建设与维护
优排软件:高效管理新天地,轻松提升工作效率,长葛外贸网站建设
为什么说seo这么重要,seo重要吗 ,ai19920403
为什么seo对企业重要,seo对企业进行网络营销的价值 ,ai李沁换脸鲍鱼
目前AI软件有哪些?智能新时代的必备工具
seo配置是什么,seo设置是什么 ,ai图标制作教程
AI写作的崛起-“只能AI写作”背后的巨大潜力,舞狮摄影ai
SEO联系:如何通过SEO优化提升您的网络营销效果,企业营销推广获客
ChatGPT无法加载?检查您的网络设置并尝试重启ChatGPT,助您畅享无障碍智能对话体验,ai记录人
SEO北京:数字时代,企业成功的关键,湖南网站建设湖南岚鸿
SEO刷:让你的网站一夜之间登顶搜索引擎!,独特seo技巧
ChatGPT页面无法翻阅?带你深度了解背后的原因与解决方案,pdf怎么转换ai文字
AI文章精简-高效提炼与优化你的内容创作,ai quid
SEO找词:如何精准找到高效关键词,提升排名和流量,河源网站优化平台
SEO阶段解析:从入门到精通,助你站稳搜索引擎的前沿,网站建设特定开发
ChatGPT页面无法下拉?禁用浏览器扩展,轻松解决!,imba 1.6 ai
SEO这样做,轻松引爆流量,助力企业成长,无极标准网站优化好处
seo营销方法是什么,seo营销模式 ,ai山海
SEO优化的利器:提升网站排名的秘密武器,联想ai7g-3笔记本
SEO站在未来之巅,助力网站在激烈竞争中脱颖而出,推荐网站优化欢迎咨询
SEO知道:让你的网站在搜索引擎中脱颖而出,水安建设集团网站
SEO优化是做什么的?让你的网站流量飙升的秘密武器,乳腺癌ai作用机理
SEO人工优化-让你的网页轻松登上搜索引擎首页,ai主母
文章写作AI:让创作更高效、精准的智能助手
seo独立站是什么,独立站推广是什么 ,ai曲线笔刷扩展
怎么用AI生成文章?全新写作方式的揭秘与应用指南
AI仿写文章:开启内容创作新纪元
优化百:开启数字时代的智能营销新时代,湘潭seo优化报价表
AI做文章:引领智能创作的未来
AI网页设计生成-智能化创造无限可能,ai机甲风背景音乐
SEO优化引导新官网,助力企业迈向成功之路,宋轶ai换
“洗稿技巧如何让你的文章脱颖而出,轻松提升内容创作水平!”,台州椒江seo企业排名
ChatGPT为什么打不开?背后原因与解决方案,慧ai写作
SEO赚钱:如何通过SEO技能在网络上实现财富自由,网站怎么建设推广平台
ChatGPT点不了?背后的真相与解决方法,ai.520523
乘风SEO-引领企业互联网时代的腾飞之路,南昌b站关键词排名优化贵不贵
亚马逊产品seo什么意思,亚马逊平台产品专业术语 ,小新同学ai