JavaScript技巧总结和本地存储(一)
- 类型检测
typeof 一般用于js的基本数据类型(undefined,number,string,boolean。注意null检测的结构是object)检测,引用类型检测不准确。
instanceof 用于检测构造函数,一般引用类型数据类型检测可以检测出来,数组一般是用这种检测方式。但如果页面嵌套的比如iframe,这种检测也会出错。
Object.prototype.toStirng.call(检测的变量)这种检测方式是最不容易出错的。
- 作用域安全的构造函数
一般我们用js声明一个类是这样声明的:
function Student(name,age){
this.name=name;
this.age=age;
}
var stu=new Student (“li lei”,20);
如果直接调用Student函数时this直接指向window对象,这样会导致name和age都声明到全局变量中,导致全局变量的污染。为了避免这种危险性,构建作用域安全构造函数,先判断this的类型。
function Student(name,age){
if(this instanceof Student){
this.name=name;
this.age=age;
} else{
return new Student (name,age)
}
}
这样直接调用Student函数返回的也是实例的对象。这种写法也有个问题,在继承类的时候要用call来调用父类的构造函数,但由于this指向的是子类导致this instanceof Student为false。
function Stu(){
Student.call(this,’name’,22);
}
解决方案是用原型继承:
Stu.prototype=new Student(‘name’,22);
但如果Stu的参数要作为Student的参数可以这么写:
function Stu(name,age){
Student.apply(this,arguments)
}
Stu.prorotype= new Student(‘name’,22);
这里把Stu原型指向Student所以Stu实例对象instanceof Stu和Student都为true。
这点其实在jQuery源码中也是这么声明jQuery函数的。因为jquery是new jquery()和jquery()都返回对象。代码如下
var aQuery = function(selector, context) {
return new aQuery.prototype.init();
}
aQuery.prototype = {
init: function() {
this.age = 18
return this;
},
name: function() {},
age: 20
}
但返回的对象要有init构造函数以及name方法。那么就要加一句:
var aQuery = function(selector, context) {
return new aQuery.prototype.init();
}
aQuery.prototype = {
init: function() {
return this;
},
name: function() {
return this.age
},
age: 20
}
aQuery.prototype.init.prototype = aQuery.prototype;
console.log(aQuery().name()) //
- 函数绑定
就是在改变函数的this指向,传统的用法是call或者apply。Es5中可以用bind
- 柯里化
之前介绍过,这里不做过多介绍
- 定时器
使用setTimeout() 和setInterval()创建的定时器可以用于实现有趣且有用的功能,这里有个注意的点:定时器不是在规定的时间就会运行,而是在规定的时间将这个函数放入到异步队列中(包括单击事件的触发都会加入到这个队列中)当进程空闲下来才执行队列中的代码。
除了主JavaScript执行进程外,还有一个需要在进程下一次空闲时执行的代码队列,随着页面的在其生命周期中的推移,代码会按照执行顺序添加入队列,例如,当某个按钮被按下时,他的事件处理程序代码就会被添加到队列中,并在下一个可能的时间里执行,当接收到某个ajax响应时,回调函数的代码会被添加到队列,在JavaScript中没有任何代码是立刻执行的,但一旦进程空闲则尽快执行。
定时器队列的工作方式是,当特定时间过去后将代码插入,注意,给队列添加代码并不意味着对它立刻执行,而只能表示它会尽快执行。设定一个150ms后执行的定时器不代表了150ms代码就立刻执行,它表示代码会在150ms后被加入到队列中,如果在这个时间点上,队列中没有其他东西,那么这段代码就会被执行,表面上看上去好像代码就在精确指定的时间上执行。其他情况下,代码可能明显等待更长时间才执行。
- 重复的定时器
使用setInterval()创建的定时确保了定时器代码规则地插入队列,这个方式的问题在于定时器代码可能在代码再次被添加发哦队列之前还没完成执行,结果导致定时器代码连续运行好几次,而之间没有任何停顿,幸好,JavaScript引擎够聪明,能避免这个问题,仅当没有该定时器的任何其他代码示例时,才将定时器代码添加发到队列中。
这种循环有两个问题:
1、 某些时间间隔会被跳过
2、 多个定时器执行之间的间隔可能会比预期的小。
为了避免这个两个问题,可以使用链式setTime()调用。
setTimeout(function(){
setTimeout(arguments.callee,interval);
})
这样可以保证在下一次定时器代码执行之前,至少要等待指定的间隔,避免了连续的运行。
- 数组分块
在数组循环处理复杂操作并且这段代码不影响后面的其他代码的单独存在,可以用定时器来推迟到进程空闲状态下在执行。避免js开始运行时间太长。逻辑写法和上面一样。
- 函数节流
有些函数或事件需要频繁调用执行的时候,为了优化性能,加入定时器在规定的时候内调用这个函数,那先把之前未执行的定时器取消,然后在重新设定定时器。这样函数的运行次数就少了很多。性能优化很多,vue的双向数据绑定,在数据驱动下,数据频繁改动导致频繁调用绑定视图函数,就是用函数节流的方式优化性能。
函数节流背后的基本思想是指,某些代码不可以在没有间断的情况连续重复执行,第一次调用函数,创建一个定时器,在指定时间间隔之后运行代码,当第二次调用该函数时,它会清除前一次的定时器并设置另一个,如果前一个定时器已经执行过了,这个操作就没有任何意义,基本形式是:
var processor={
timeoutId:null,
performProcessing:function(){},
process:function(){
clearTimeout(this.timeoutId);
this.timeoutId=setTimeout(function(){
that.performProcessing();
},100);
}
}
(二):自定义事件、拖放、添加自定义事件、离线应用和客户存储
JavaScript技巧总结和本地存储(一)的更多相关文章
- JavaScript技巧总结和本地存储(二)
离线检测 检测是否离线,html5为此定义了一个navigator.onLine属性,这个属性为true表示设备能上网,false表示离线,这个属性还有点兼容问题.因此单独使用这个属性不能确定网络是否 ...
- JavaScript:浏览器的本地存储
cookie.localStorage.sessionStorage的使用 <!DOCTYPE html> <html lang="en"> <hea ...
- HTML5 学习总结(三)——本地存储
一.HTML4客户端存储 B/S架构的应用大量的信息存储在服务器端,客户端通过请求响应的方式从服务器获得数据,这样集中存储也会给服务器带来相应的压力,有些数据可以直接存储在客户端,传统的Web技术中会 ...
- HTML5 学习笔记(三)——本地存储
目录 一.HTML4客户端存储 1.1.提交表单发送到服务器的信息 1.2.客户端本地存储概要 二.localStorage 2.1.添加 2.2.取值 2.3.修改 2.4.删除 2.5.跨页面与跨 ...
- HTML5 学习笔记(三)——本地存储(LocalStorage、SessionStorage、Web SQL Database)
一.HTML4客户端存储 B/S架构的应用大量的信息存储在服务器端,客户端通过请求响应的方式从服务器获得数据,这样集中存储也会给服务器带来相应的压力,有些数据可以直接存储在客户端,传统的Web技术中会 ...
- HTML5 ——本地存储
目录 一.HTML4客户端存储 1.1.提交表单发送到服务器的信息 1.2.客户端本地存储概要 二.localStorage 2.1.添加 2.2.取值 2.3.修改 2.4.删除 2.5.跨页面与跨 ...
- HTML5 学习总结(三)——本地存储(localStorage、sessionStorage、WebSqlDataBase、IndexedDB)
HTML5问世以后,前端加入了一个重要的功能,便是本地存储,本地存储可分为4类: Local Storage:总的存储量有所限制,并不能提供真正的检索API,数据的生命期比窗口或浏览器的生命期长,数据 ...
- web前端实现本地存储
当我们在提及web前端本地存储的时候,首先需要介绍一下本地化存储的概念和历史.本地化存储从来不是一个新奇的概念,因为web应用程序一直在追求的就是媲美甚至超越桌面应用程序.但是桌面应用程序一直优于we ...
- Javascript本地存储小结
前言 总括:详细讲述Cookie,LocalStorge,SesstionStorge的区别和用法. 人生如画,岁月如歌. 原文博客地址:Javascript本地存储小结 知乎专栏&& ...
随机推荐
- robotium从入门到放弃 二 第一个实例
1.导入被测试的源码 我们先下载加你计算器源码,下载地址: https://robotium.googlecode.com/files/AndroidCalculator.zip 如果地址被墙无法现在 ...
- js原生设计模式——2面向对象编程之继承—new+call(this)组合式继承
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8&qu ...
- 聚类系数(clustering coefficient)计算
转自http://blog.csdn.net/pennyliang/article/details/6838956 Clustering coefficient的定义有两种:全局的和局部的. 全局的算 ...
- doubango(4)--SIP协议栈传输层的启动
协议栈的默认传输结构 对于一个刚启动的协议栈来说,它需要有一个传输层,支持若干的传输结点.每一个传输结点对应于一个端口,若采用TCP连接,一个传输结点就针对于一个点到点的连接,这个连接负责sip信令的 ...
- 基于basys2驱动LCDQC12864B的verilog设计图片显示
话不多说先上图 前言 在做这个实验的时候在网上找了许多资料,都是关于使用单片机驱动LCD显示,确实用单片机驱动是要简单不少,记得在FPGA学习交流群里问问题的时候,被前辈指教,说给我最好的指教便是别在 ...
- JDK1.8源码阅读系列之三:Vector
本篇随笔主要描述的是我阅读 Vector 源码期间的对于 Vector 的一些实现上的个人理解,用于个人备忘,有不对的地方,请指出- 先来看一下 Vector 的继承图: 可以看出,Vector 的直 ...
- iOS页面间传值的五种方式总结(Delegate/NSNotification/Block/NSUserDefault/单例)
iOS页面间传值的方式(Delegate/NSNotification/Block/NSUserDefault/单例) iOS页面间传值的方式(NSUserDefault/Delegate/NSNot ...
- MySQL 存储表情字符
摘要 在 MySQL 中直接存储表情的时候,会出现无法插入数据的错误. 这是由于一般情况下,MySQL 的字符集是 utf8,而对于 emoji 表情的 mysql 的 utf8 字符集是不支持,需要 ...
- 《JAVASCRIPT高级程序设计》事件委托和模拟事件
由于事件处理程序可以为现代web应用提供交互能力,因此许多开发人员不分青红皂白向页面中添加大量的处理程序:这在某些语言中不会导致问题,但是在javascript,事件处理程序数量直接关系到页面的整体运 ...
- Yii2前后台分离
Yii2前后台都需要注册的时候会产生前后台登录一个另一个同步登录和退出,这是因为登录和退出之前的sitecontroller里面公用了common/model下面的LoginForm.php和user ...