/**
* 用js实现一个类P 包含成员变量a,成员变量b成员函数sum sum输出a与b的和,a,b默认值都为0.实现一个类M,M继承自P,在P的基础上增加成员变量c成员变量函数sum变成a,b,c的和
*/
function P(a,b){
this.a = a || 0;
this.b = b || 0;
}
P.prototype.sum = function(){
return this.a + this.b;
};
function M(a,b,c){
P.call(this,a,b);
this.c = c || 0;
}
M.prototype = new P();
M.prototype.constructor = M;
M.prototype.sum = function(){
return this.a + this.b + this.c;
};
var p = new P(1,2);
var m = new M(1,2,3);
console.log("p.sum()=",p.sum());
console.log("m.sum()=",m.sum());
/**
* 写出三个不同的this使用场景
*/
// 0. 构造器函数内的this:
//如果函数创建的目的是使用new来调用,并产生一个对象,那么此函数被称为 构造器函数。
// var Niu = function (string) {
//
// this.name = string;
// };
// 上述的Niu即为一个构造器函数,其内部的this会自动绑定到new所创建的新对象上面。
//
// 1. 对象成员方法内的this:
// 对象的成员方法中的this是对象本身,此时跟其它语言是一致的,但是也有差异,javascript中this到对象的绑定发生在函数调用的时候。
//
// var myObj = {
//
// value: 0,
//
// increment: function (inc) {
//
// this.value += typeof inc === 'number' ? inc : 1;
//
// }
//
// };
//
// myObj.increment(); //1
//
// myObj.increment(2); //3
// 2. 普通函数 与 闭包内的this:
//
// 2.1 以普通方式定义的函数中的this:会被自动绑定到全局对象。
// var value = 232;
//
// function toStr()
//
// {
//
// console.log("%d", this.value); //232
//
// }
//
//
// 2.2 对象方法中闭包函数的this:
//
// 由2.1可知,在以普通方式定义的函数中的this会被自动绑定到全局对象上,大家应该可以看出闭包函数定义也与普通方式无异,因此他也会被绑定到全局对象上。
//
// value = 10;
var closureThis = {
// value: 0,
// acc: function ()
// {
// var helper = function ()
// {
// this.value += 2;
// console.log("this.value : %d", this.value);
// }
// helper();
// }
// };
//
// closureThis.acc(); //12
// closureThis.acc(); //14
//
// var closureThat = {
// value: 0,
// acc: function ()
// {
// that = this;
// var helper = function ()
// {
// that.value += 2;
// console.log("that.value : %d", that.value);
// }
// helper();
// }
// };
//
// closureThat.acc(); // 2
// closureThat.acc(); // 4
// 从上述输出值可以看出,上述描述的正确性。
//
// 3. Apply函数的参数this:
//
// appy方法允许我们选择一个this值作为第一个参数传递,第二个参数是一个数组,表明可以传递多个参数。
//【场景1】全局环境中的this指向全局对象
// this.a = 10;
// alert(a);//10
// b = 20;
// alert(this.b);//20
// var c = 30;
// alert(this.c);//30
// 【场景2】对象内部函数的this指向调用函数的当前对象
// var a = 10;
// var bar = {
// a: 20,
// test: function(){
// alert(this.a);
// }
// }
// bar.test();//20
// 【场景3】全局环境函数的this指向全局对象
// var a = 10;
// function foo(){
// alert(this.a);
// }
// foo();//10
// 【场景4】匿名函数中的this指向全局对象
// var a = 10;
// var foo = {
// a: 20,
// fn: (function(){
// alert(this.a);
// })()
// }
// foo.fn//10
// 【场景5】setInterval和setTimeout定时器中的this指向全局对象
// var a = 10;
// var oTimer1 = setInterval(function(){
// var a = 20;
// alert(this.a);//10
// clearInterval(oTimer1);
// },100);
// 【场景6】eval中的this指向调用上下文中的this
// (function(){
// eval("alert(this)");//[object Window]
// })();
// function Foo(){
// this.bar = function(){
// eval("alert(this)");//[object Object]
// }
// }
// var foo = new Foo();
// foo.bar();
// 【场景7】构造函数中的this指向构造出的新对象
// function Person(name,age){
// this.name = name;
// this.age = age;
// this.sayName = function(){
// alert(this.name);
// }
// }
// var p1 = new Person('lily','20');
// p1.sayName();//'lily'
// 【场景8】new Function中的this指向全局对象
// (function(){
// var f = new Function("alert(this)");
// f();//[object Window]
// })();
// function Foo(){
// this.bar = function(){
// var f = new Function("alert(this)");
// f();//[object Window]
// }
// }
// var foo = new Foo();
// foo.bar();
// 【场景9】apply和call中的this指向参数中的对象
// var a = 10;
// var foo = {
// a: 20,
// fn: function(){
// alert(this.a);
// }
// };
// var bar ={
// a: 30
// }
// foo.fn.apply();//10(若参数为空,默认指向全局对象)
// foo.fn.apply(foo);//20
// foo.fn.apply(bar);//30
// 【复合场景1】
// var someone = {
// name: "Bob",
// showName: function(){
// alert(this.name);
// }
// };
// var other = {
// name: "Tom",
// showName: someone.showName
// }
// other.showName(); //Tom
//
// //以上函数相当于
//
// var other = {
// name: "Tom",
// showName: function(){
// alert(this.name);
// }
// }
// other.showName(); //Tom
// 【复合场景2】
// var name = 2;
// var a = {
// name: 3,
// fn: (function(){
// alert(this.name);
// })(),
// fn1:function(){
// alert(this.name);
// }
// }
// a.fn;//2[匿名函数中的this指向全局对象]
// a.fn1();//3[对象内部函数的this指向调用函数的当前对象]
//
// 【复合场景3】
// var name = "Bob";
// var nameObj ={
// name : "Tom",
// showName : function(){
// alert(this.name);
// },
// waitShowName : function(){
// var that = this;
// setTimeout(function(){
// that.showName();
// }, 1000);
// }
// };
// nameObj.waitShowName();//"Tom"[that=this改变this的指向,使this从指向全局变量变化到指向nameObj]
//
// var name = "Bob";
// var nameObj ={
// name : "Tom",
// showName : function(){
// alert(this.name);
// },
// waitShowName : function(){
// var that = this;//that指向nameObj
// setTimeout(function(){
// (function(){
// alert(this.name);
// })();
// }, 1000);
// }
// };
// nameObj.waitShowName();// 'Bob'[形成匿名函数,this指向全局变量]
/**
* 写出下面这段代码的执行结果
*/
for(var i = 0 ; i < 3 ; i ++){
setTimeout(function(){
console.log(i);
},0);
}
/**
* 执行结果:
* 3
* 3
* 3
* 原因:js是单程的,会先执行for然后有空闲的时候再执行setTimeout,虽然setTimeout的时间延时为0,还是会缓存等待for循环执行结束之后等有空闲的时候再执行
*/
/**
* 说出以下函数的作用,并填写空格内容
*/
//define
(function(window){
function fn(str){
this.str = str;
}
fn.prototype.format = function(){
var arg = ____;
return this.str.replace(____,function(a,b){
return arg[b] || "";
});
};
window.fn = fn;
})(window);
//use
(function(){
var t = new fn('{1}{2}
');
console.log(t.format('http://www.baidu.com','BaiDuSecurites','Welcome'));
})();
/**
* 将字符串中的特定字符用函数的参数来替换
*/
//define 这里是一个私有作用域,为了让外面的函数可以访问到fn函数,传入了window对象,并且最终将定义的函数赋值到了window中的fn上了,所以外面可以访问到
(function(window){
function fn(str){
this.str=str;
}
fn.prototype.format=function(){
var arg=arguments;
return this.str.replace(/\{(\d+)\}/ig,function(a,b){
// console.log(a);
// console.log(arg);
// console.log(b);
console.log(arg[b]);
return arg[b]||'';
});
}
window.fn=fn;
})(window);
//use
(function(){
var t=new fn('{1}{2}
');
console.log(t.format('http://www.alibaba.com','Alibaba','Welcome'));
})();
/**
* 用js实现一个Promise,要求支持resolve,reject,done,fail,then,always.
*/
// state: 当前执行状态,有pending、resolved、rejected3种取值
//
// done: 向doneList中添加一个成功回调函数
//
// fail: 向failList中添加一个失败回调函数
//
// then: 分别向doneList和failList中添加回调函数
//
// always: 添加一个无论成功还是失败都会调用的回调函数
//
// resolve: 将状态更改为resolved,并触发绑定的所有成功的回调函数
//
// reject: 将状态更改为rejected,并触发绑定的所有失败的回调函数
//
// when: 参数是多个异步或者延迟函数,返回值是一个Promise兑现,当所有函数都执行成功的时候执行该对象的resolve方法,反之执行该对象的reject方法
// 下面是我的具体实现过程:
var Promise = function() {
this.doneList = [];
this.failList = [];
this.state = 'pending';
};
Promise.prototype = {
constructor: 'Promise',
resolve: function() {
this.state = 'resolved';
var list = this.doneList;
for(var i = 0, len = list.length; i < len; i++) {
list[0].call(this);
list.shift();
}
},
reject: function() {
this.state = 'rejected';
var list = this.failList;
for(var i = 0, len = list.length; i < len; i++){
list[0].call(this);
list.shift();
}
},
done: function(func) {
if(typeof func === 'function') {
this.doneList.push(func);
}
return this;
},
fail: function(func) {
if(typeof func === 'function') {
this.failList.push(func);
}
return this;
},
then: function(doneFn, failFn) {
this.done(doneFn).fail(failFn);
return this;
},
always: function(fn) {
this.done(fn).fail(fn);
return this;
}
};
function when() {
var p = new Promise();
var success = true;
var len = arguments.length;
for(var i = 0; i < len; i++) {
if(!(arguments[i] instanceof Promise)) {
return false;
}
else {
arguments[i].always(function() {
if(this.state != 'resolved'){
success = false;
}
len--;
if(len == 0) {
success ? p.resolve() : p.reject();
}
});
}
}
return p;
}
// Improve
// 目前只是实现了Promise的基础功能,但仍然还有无法处理的情况,例如要实现3个或3个以上的异步请求的串行,目前我的Promise没有办法支持new Promise(A).then(B).then(C)这样的形式,jQuery在1.7的版本中为Deferred(Promise)对象实现了pipe函数,可以通过这个函数实现上述功能,代码为$.Deferred(A).pipe(B).then(C),我尝试去读了jQuery这部分的代码,但是没能读懂,希望有大神能够给一些实现思路
/**
* 两个顺序排列的数组A和B,求B数组是否为A数组的子集。(数组内可能有重复数字)
*/
var A = [1,2,2,2,2,3,5,5,5,6,8,9,9,9];
var B = [1,2,3];
/**
* A,B,分别是两个顺序排列的数组,判断B是否为A的子集
* @param _A
* @param _B
* @returns {boolean}
*/
function isASon(_A,_B){
var flag = false;
if(_A instanceof Array && _B instanceof Array){
var i = 0,j = 0 ;
while(i < _B.length){
flag = false;
for( ; j < _A.length ; j ++){
if(_B[i] === _A[j] ){
flag = true;
break;
}
}
if(flag){
i ++;
}else{
return false;
}
}
if(flag){
return true ;
}else{
return false;
}
}
}
isASon(A,B);