一、this绑定
//this绑定,立即执行函数表达式 var num = 1; var myObject = { num:2, add:function(){ this.num = 3; (function(){ console.log(this.num); this.num = 4; })(); console.log(this.num); }, sub:function(){ console.log(this.num); } } myObject.add(); console.log(myObject.num); console.log(num); var sub = myObject.sub; sub(); //结果 1 3 3 4 4
var number = 5; var obj = { number: 3, fn1: (function () { var number; this.number *= 2; number = number * 2; number = 3; return function () { var num = this.number; this.number *= 2; console.log(num); number *= 3; console.log(number); } })() } var fn1 = obj.fn1; fn1.call(null); obj.fn1(); console.log(window.number); //结果 10 9 3 27 20
二、函数调用(函数表达式、箭头函数)
var name = 'window' var person1 = { name:'person1', show1:function(){ console.log(this.name); }, show2:()=>console.log(this.name), show3:function(){ return function(){ console.log(this.name); } }, show4:function(){ return ()=>console.log(this.name) } } var person2 = {name:'person2'}; person1.show1();//person1 person1.show1.call(person2);//person2 person1.show2();//window person1.show2.call(person2);//window person1.show3()();//person1错 window person1.show3().call(person2);//person2 person1.show3.call(person2)();//person2错 window person1.show4()();//window错 person1 person1.show4().call(person2);//person1 person1.show4.call(person2)();//window错 person2
var name = "hanmeimei"; var f = function(){ var name = "lilei"; return function(){ console.log(this.name); } } f()();//hanmeimei
三、10个随机数,不重复
function getRandom(num){ var numb = []; var newArr = []; while(numb.length<num){ let n = parseInt(Math.random() * 32); if(n>=2&&n<=32){ numb.push(n); newArr = Array.from(new Set(numb)); } } console.log(newArr); //return newArr; } getRandom(10);
四、数组展开函数
// 写出一个数组展开函数, 如输入:[1,[2,[3,4,2],2],5,[6]], 则输出:[1,2,3,4,2,2,5,6] // 因为和深度无关,所以说最简单可以这样 function flatten(arr){ var res = arr.join().split(','); res = res.map( ele => +ele) return res; } // 还有吗,递归,写一下 function flatten(arr){ var array = []; arr.forEach(ele => { if(Array.isArray(ele)){ array.push(...flatten(ele)); } else { array.push(ele); } }) return array; } var arr1 = [1,[2,[3,4,2],2],5,[6]]; flatten(arr1)
五、eventloop
console.log('begin'); setTimeout(() => { console.log('setTimeout 1'); Promise.resolve().then(() => { console.log('promise 1'); setTimeout(() => { console.log('setTimeout2 between promise1&2'); }) }).then(() => { console.log('promise 2'); }); }, 0); console.log('end');
begin
end
setTimeout 1
promise 1
promise 2
setTimeout2 between promise1&2
console.log('script start') async function async1() { await async2() console.log('async1 end') } async function async2() { console.log('async2 end') } async1() setTimeout(function() { console.log('setTimeout') }, 0) new Promise(resolve => { console.log('Promise') resolve() }) .then(function() { console.log('promise1') }) .then(function() { console.log('promise2') }) console.log('script end') //结果 script start end Promise end end promise1 promise2 undefined setTimeout
六、基本数据类型判断
console.log(Number([1])) if([]==false){console.log(1)}//1 if({}==false){console.log(2)} if([]){console.log(3)}//3 if([1]==[1]){console.log(4)}
七、裴波纳锲数列
function Fibonacci(n) { if (n == 0) { return 1; } var pre = 1, // 前一个值 cur = 1; // 当前值 for (var i = 2; i <= n; i++) { // 更新两个值 cur += pre; pre = cur - pre; } return cur; } function Fibonacci2(n) { var f = [0, 1]; for(let i = 2; i <= n; i++) { f[i] = f[i - 1] + f[i - 2]; } return f[n]; } Fibonacci(5)
function fibonacci(n){ if(n==1||n==2) return 1; return fibonacci(n-1)+fibonacci(n-2); }
八、读取url中的参数
var getUrlParam2 = function(sUrl, sKey){ // 捕获组两枚,一枚负责Key 一枚负责获取Value var reg = new RegExp('([0-9a-zA-Z%]+)=([0-9a-zA-Z%]+)&*', 'ig'); // 结果集保存 var result = {}; var temp; var key, value; while(temp = reg.exec(sUrl)) { key = temp[1]; value = temp[2]; if (result[key] && !(result[key] instanceof Array)) { result[key] = [result[key], value]; // 如果发现了第二个同名参数,则从字符串变为数组 } else if (result[key] instanceof Array) { result[key].push(value); // 已经是数组,又找到了,就push进去 } else { result[key] = value; // 第一次,还是普通保存 } } if (sKey) { return result[sKey] ? result[sKey] : ''; // 为了避免undefined的情况 } else { return result; // 返回全部的对象参数 } } getUrlParam2("http://www.nowcoder.com?key=1&key=2&key=3&test=4#hehe")
九、jsonp
//http://www.baidu.com?aa=11&callback=my_jsonp04349289664328899 var jsonp = function(url,param,callback){ //处理url地址,查找?,如果没有?这个变量就有一个"?",有?这个变量接收一个& var querystring = url.indexOf("?") == -1?"?":"&"; //处理参数{xx:xx} for(var k in param) { querystring += k + "=" + param[k] + '&';//?k=para[k] } //处理回调函数名 var random = Math.random().toString().replace(".",""); var cbval = "my_jsonp" + random; var cb = "callback="+cbval; querystring += cb; var script = document.createElement("script"); script.src = url + querystring; //把回调函数的名字附给window window[cbval] = function(param) { //这里执行回调的操作,用回调来处理参数 callback(param); //拿到了就删掉这个script document.body.removeChild(script); }; document.body.appendChild(script); } jsonp( "https://www.baidu.com", {aa:11}, function(){ console.log(param); } );
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title> <script type="text/javascript"> // 得到航班信息查询结果后的回调函数 var flightHandler = function(data){ alert('你查询的航班结果是:票价 ' + data.price + ' 元,' + '余票 ' + data.tickets + ' 张。'); }; // 提供jsonp服务的url地址(不管是什么类型的地址,最终生成的返回值都是一段javascript代码) var url = "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998&callback=flightHandler"; // 创建script标签,设置其属性 var script = document.createElement('script'); script.setAttribute('src', url); // 把script标签加入head,此时调用开始 document.getElementsByTagName('head')[0].appendChild(script); </script> </head> <body> </body> </html>
十、深克隆
//js的深克隆 function deepCopy(obj){ //判断是否是简单数据类型, if(typeof obj == "object"){ //复杂数据类型 var result = obj.constructor == Array ? [] : {}; for(let i in obj){ result[i] = typeof obj[i] == "object" ? deepCopy(obj[i]) : obj[i]; } }else { //简单数据类型 直接 == 赋值 var result = obj; } return result; }
十一、判断是否是数组
//判断是否为数组 通过toString()方法 通过constructor 通过instanceof Array.isArray var arr = [1, 2, 3]; var obj = { name: 'lyl', age: 18, 1: 'name' } console.log(Object.prototype.toString.call(arr) === '[object Array]'); //true console.log(Object.prototype.toString.call(boj) === '[object Array]'); //false
十二、promise
// 这里我们创建了一个构造函数 参数就是执行器 function Promise(exector) { // 这里我们将value 成功时候的值 reason失败时候的值放入属性中 let self = this; // 这里我们加入一个状态标识 this.status = 'pending'; this.value = undefined; this.reason = undefined; // 成功执行 function resolve(value) { // 判断是否处于pending状态 if (self.status === 'pending') { self.value = value; // 这里我们执行之后需要更改状态 self.status = 'resolved'; } } // 失败执行 function reject(reason) { // 判断是否处于pending状态 if (self.status === 'pending') { self.reason = reason; // 这里我们执行之后需要更改状态 self.status = 'rejected'; } } // 这里对异常进行处理 try { exector(resolve, reject); } catch(e) { reject(e) } } // 我们将then方法添加到构造函数的原型上 参数分别为成功和失败的回调 Promise.prototype.then = function(onFulfilled, onRejected) { // 获取下this let self = this; if (this.status === 'resolved') { onFulfilled(self.value); } if (this.status === 'rejected') { onRejected(self.reason); } } //运行 let promise = new Promise((resolve, reject) => { resolve("haha"); }) promise.then(data => { console.log(data); //输出 haha }, err=> { console.log(err); }) // 多次调用 promise.then(data => { console.log(data); //输出 haha }, err=> { console.log(err); })
十三、JS如何判断一组数字是否连续
// 当出现连续数字的时候以‘-’输出 [1, 2, 3, 4, 6, 8, 9, 10] // 期望结果 ["1-4", 6, "8-10"] var arrange = function(arr){ var result = [],temp = []; arr.sort(function(source, dest){ return source - dest; }).concat(Infinity).reduce(function(source, dest){ temp.push(source); if(dest-source > 1){ result.push(temp); temp = []; } return dest; }); return result; }; var formatarr = function(arr) { var newArr = [] var arr1 = arrange(arr) for (var i in arr1) { var str = ''; if (arr1[i].length > 1) { str = arr1[i][0] + '-' + arr1[i][arr1[i].length - 1]; newArr.push(str) } else { newArr.push(arr1[i][0]); } } return newArr; }
十四、请自定义一个函数,实现字符串反转。
function revStr(str){ var temStr = ""; var len = str.length; for(var i=len-1;i>=0;i--){ temStr = str.charAt(i); } return temStr; } //字符串的完全翻转 str.split("").reverse().join("") //翻转字符串中单词顺序,但单词字母顺序不变,注意:单词间可能有多空格,并且前后可能也有空格 function reverseStr(param){ var arr = param.split(/\s+/); var newArr = []; for(i=0;i<arr.length;i++){ newArr[arr.length-i] = arr[i]; } return newArr.join(" ").trim(); } document.write(reverseStr("smile at life"));
十五、JavaScript中如何检测一个变量是一个string/数组类型?
var str = "hello world";
function isString(str){
if(typeof str == "string" || str.constructor == String){
return true;
}else{
return false;
}
}
if(typeof Array.isArray==='undefined'){
Array.isArray=function(arg){
return Object.prototype.tostring.call(rag)==='[Object Array]';
};
}
十六、找到第一个数组array1中出现,而在第二个数组array2中没有出现的数字
function findNullOfNum(arr1,arr2){ var str = arr2.split(""); var result = []; for(var i=0,x=0;i<arr1.length;i++){ if(str.indexOf(arr1[i] == -1){ result[x] = arr1[i]; x++; } } return result; }
十七、数组去重
function select(arr){ var temp=[]; for(var i = 0;i < arr.length;i++){ //indexOf() 方法可返回某个指定的字符串值在字符串中首次出现的位置。ie8不兼容 if(temp.indexOf(arr[i]) == -1){ temp.push(arr[i]); } } return temp; } //具体验证 var arr=[4,5,1,53,5,1,3]; console.log(select(arr)); //includes():判断当前数组是否包含某个值,若有则返回true,若没有则返回false; function select(arr){ var temp=[]; arr.forEach((v)=>{ temp.includes(v)||temp.push(v); }) return temp; } //循环判断 function select(arr){ var temp=[]; for(var i = 0; i < arr.length; i++){ for(var j = i+1; j < arr.length; j++){ if(arr[i] === arr[j]){ j = ++i; } } temp.push(arr[i]); } return temp; }
//输入[false, true, undefined, null, NaN, 0, 1, {}, {}, 'a', 'a', NaN] //输出[false, true, undefined, null, NaN, 0, 1, {}, {}, 'a'] Array.prototype.uniq = function () { var resArr = []; var flag = true; for(var i=0;i<this.length;i++){ if(resArr.indexOf(this[i]) == -1){ if(this[i] != this[i]){ //排除 NaN if(flag){ resArr.push(this[i]); flag = false; } }else{ resArr.push(this[i]); } } } return resArr; }
十八、字符串全排列
function Permutation(str) { let res=[]; if(str.length<=0) return res; arr=str.split("");//将字符串转化为字符数组 res=permutate(arr,0,res); res=[...new Set(res)];//去重 res.sort();//排序 return res; } function permutate(arr,index,res){ if(arr.length==index){ let s=""; for(let i=0;i<arr.length;i++){ s+=arr[i]; } return res.push(s); }else{ for(let i=index;i<arr.length;i++){ [arr[index],arr[i]]=[arr[i],arr[index]];//交换 permutate(arr,index+1,res); [arr[index],arr[i]]=[arr[i],arr[index]];//交换 } } return res; }
十九、找出数组中重复数字
function findSame(arr) { let map = {}, res=[]; for (let i = 0; i < arr.length; i++) { if (!map[arr[i]]) { map[arr[i]] = 1; } else { map[arr[i]]++; } } for (let i in map) { if (map[i] > 1) { res.push(i); } } return res; }
二十、转换obj
var obj =[ {id: 1, parent: null}, {id: 2, parent: 1}, {id: 3, parent: 2}, ] function transform(obj, index) { let node; if(obj.length - 1 == index){ node = { id: obj[index].id, parent: obj[index].parent } }else{ node = { id: obj[index].id, parent: obj[index].parent, child: transform(obj,++index) } } return node; } let obj2 = { obj: transform(obj, 0) } console.log(obj2);
二十一、实现log函数
function log(...args){ let str = args.join(" "); return "(app)"+str; }
二十二、动态插入p标签
let p = document.createElement("p"); p.setAttribute("class", "pdd-slogan"); p.textContent = "多拼多实惠" div.appendChild(p); document.body.appendChild(div);
二十三、let a = new A("test");发生了什么?(笔试简答题)
1.先对A构造函数RHS查询标识符。
2.使用new 调用构造函数A
//创建一个新的对象,并设置__proto__
//将构造函数的作用域赋值给新对象(因此this就指向了这个新对象)
//执行函数中的代码(为这个对象添加新的属性)
//返回这个新的对象
//将构造函数的作用域赋值给新对象(因此this就指向了这个新对象)
//执行函数中的代码(为这个对象添加新的属性)
//返回这个新的对象
3.创建变量a,并把之前的调用结果赋值给变量a
下面是new的原理实现
//实现一个new方法 function New(f) { //返回一个func return function () { var o = {"__proto__": f.prototype}; f.apply(o, arguments);//继承父类的属性 return o; //返回一个Object } }
二十四、输入一个数字,不以0开头,找到相同数字组合的最小数字
function nextSmaller (num) { // your code here 例:输入:210215,输出:101225 输入:21,输出:12 找不到满足的输出-1 var arr = num.toString().split(""); if(arr[0]!=0){ arr.sort(); console.log(arr); var i = 0; while(arr[i]==0){ i = i+1; } if(i!=0){ arr[0] = arr[i]; arr[i] = 0; } if(num>=parseInt(arr.join(""))){ return parseInt(arr.join("")); }else{ return -1; } }else{ return -1; } }
后续会继续补充······