js中setTimeout与setInterval之魔法进阶篇

没有被传进去,分别用chrome,firefox和IE9实验了下,都是这个结果

解决方法一:

<script type="text/javascript">
 function shape(name) {
 this.name = name;
 this.timer = function(){alert('my shape is '+this.name)};
 var _this = this;
 setTimeout(function() {_this.timer.call(_this)}, 50);
 }
 new shape('rectangle');
</script>

设置一个局部变量_this,然后放到setTimeout的函数变量中,timer执行call或apply,设置this值。

function能够调用局部变量_this,多亏了Javascript的闭包。里面涉及了作用域链等知识,有兴趣的可以自己去了解下,这里不展开了

定时器中的事件

setTimeout定时器对队列的工作方式:当特定时间过去后将代码添加到队列中,但并不意味着会马上将执行,设定一个200ms后执行的定时器,指的是在200ms后它将被添加到队列中,是否执行,还得看队列中是否没有其他的东西。看一下例子:

var a=document.getElementById("nav");
 a.onclick=function(){
 setTimeout(alertsomething,200);
 //一些其他的代码
}
function alertsomething(){
 alert("it is working");
}

假定onclick处理程序需要执行300ms,这时虽然在205ms添加了定时器代码,但是仍旧需要等待onclick事件完成后才能够执行。如图所示,本来在205ms处添加了定时器代码,但是由于此时onclick事件还没结束,故要等到300ms后才执行定时器代码。

js中setTimeout与setInterval之魔法进阶篇

setInterval:为了避免多个定时器代码不间断连续运行好几次,当使用setInterval(),仅当没有该定时器的任何其他代码实例时,才将定时器代码添加到队列中,通俗点就是等到上个定时器完成,再添加一个。

缺点:

1.某些间隔会被跳过

2.多个定时器的代码执行之间的间隔可能会比预期小。

时间:1年前 (2017/07/02) / 阅读:228 / 评论:0

js中setTimeout与setInterval之魔法进阶篇

详解javascript 中的各种继承方式的优点和缺点

一 原型继承

let Super = functioin(name) {

this.name = name;

this.setName = (newName) => {

this.name = name;

};

this.getName = () => {

return this.name;

}

}

let Sub = function(sex) {

this.sex = sex;

}

Sub.prototype = new Super('eric'); //通过改变原型对象实现继承

let sub1 = new Sub('male')

sub2 = new Sub('female');

sub1.setName('ada');

// 这里必须通过setName方法来修改继承来的name属性。

// 如果通过sub1.name== 'ada',就打不到目的,因为此时sub1对象上没有name属性,

// 这样等于为该对象添加了新的属性,而不是修改继承而来的name属性。

console.log(sub2.name); // ada,可见此sub2的name也会被修改掉

console.log(sub1.getName === sub2.getName) // true,复用了方法

优点:父类的方法(getName)得到了复用。

缺点:同理父类的属性(name)也是复用,即子类实例没有自己的属性。

二 构造函数实现继承

let Super = function(name) {

this.name = name;

this.getName = () => {

return this.name;

}

}

let Sub = function(sex,name) {

Super.call(this,name); // 调用父类方法为子类实例添加属性

this.sex = sex;

}

let sub1 = new Sub('male','eric'),

sub2 = new Sub('female','eric');

sub1.name = 'ada';

console.log(sub2.name); // eric,实例的属性没有相互影响

console.log(sub1.getName === sub2.getName); // false,可见方法没有复用

优点:子类的每个实例都有自己的属性(name),不会相互影响。

缺点:但是继承父类方法的时候就不需要这种特性,没有实现父类方法的复用。

三 组合式继承

let Super = function(name) {

this.name = name;

}

Super.prototype = {

constructor: Super, // 保持构造函数和原型对象的完整性

getName() {

return this.name;

}

}

let Sub = function(sex) {

Super.call(this,'eric'); //继承父类属性

this.sex = sex;

}

Sub.prototype = new Super('eric'); //继承父类方法

Sub.prototype.constructor = Sub;

let sub1 = new Sub('male'),

sub2 = new Sub('female');

// 可以按上述两种方法验证,复用了父类的方法,实例没有复用,达到目的

优点:继承了上述两种方式的优点,摒弃了缺点,复用了方法,子类又有各自的属性。

缺点:因为父类构造函数被执行了两次,子类的原型对象(Sub.prototype)中也有一份父类的实例属性,而且这些属性会被子类实例(sub1,sub2)的属性覆盖掉,也存在内存浪费。

四 寄生组合式继承

let Super = function(name) {

this.name = name;

}

Super.prototype = {

constructor: Super,

getName() {

return this.name;

}

}

let Sub = function(sex,name) {

Super.call(this,name);

this.sex = sex;

}

// 组合继承的缺点就是在继承父类方法的时候调用了父类构造函数,从而造成内存浪费,

// 现在只要解决了这个问题就完美了。那在复用父类方法的时候,

// 使用Object.create方法也可以达到目的,没有调用父类构造函数,问题解决。

Sub.prototype = Object.create(Super.prototype);

Sub.prototype.constructor = Sub;

五 es6中的class

class Super() {

constructor(props) {

this.name = props.name |"/>

时间:1年前 (2017/07/01) / 阅读:296 / 评论:0

详解javascript 中的各种继承方式的优点和缺点