this关键字
- 普通函数中的this window
- 构造函数中的this 是当前构造函数创建的对象在new这个构造函数的时候会在内存中创建一个对象,此时会让this指向刚创建好的这个对象
- 方法中的this 方法所属的对象,谁调用这个方法this就指向谁
- 事件处理函数中的this 事件源 谁调用的该事件this就指向谁在这里就指向事件源this
call,apply,bind 三者用法和区别
-
改变函数内部的this指向
-
call()
call 方法第一个参数作为函数上下文的对象,但是后面传入的是一个参数列表,而不是数组。
function a(xx) { this.b = xx; } var o = {}; a.call(o, 5); console.log(a.b); // undefined console.log(o.b); // 5 -
apply()
apply 方法传入两个参数:一个是作为函数上下文的对象,另外一个是作为函数参数所组成的数组。
function add(a,b) { this.sum = a + b; } var o = {}; add.call(o, 5,5); console.log(o.sum); // 10 add.apply(o,[3,5]); console.log(o.sum); // 8 -
bind()
bind()的作用其实与call()以及apply()都是一样的,都是为了改变函数运行时的上下文,bind()与后面两者的区别是,call()和apply()在调用函数之后会立即执行,而bind()方法调用并改变函数运行时的上下文的之后,返回一个新的函数,在我们需要调用的地方去调用他。
var a = 1; var obj = { a=9; }; function example(b){ return this.a+b }; console.log(example.bind(obj,2)); // 打印出来的是一个函数 不会立即执行 var newexample = example(); newexample(); // 调用的地方去调用
跨域问题
-
产生跨域的原因:浏览器的同源策略。
-
什么是同源策略:同源是指域名,协议,端口三个都相同。
-
例子:
www.jianshu.com 和jianshu.com 不同源,因为域名不同
www.bilibili.tv和http://www.bilibili.com 不同源,因为域名不同
http://localhost:3000 和 http://localhost:3001 不同源,因为端口不同
qq.com 和https://qq.com 不同源,因为协议不同
www.pixiv.net 和 www.pixiv.net/manage/illu… 同源,因为域名,协议,端口都相同
-
-
如何解决跨域
- 后端代理:后端不存在跨域
- cros(xhr2):设置请求头
- jsonp:利用script的src属性不存在跨域的特性;请求方式:get
- nginx(最好的)
事件委托(代理)
-
事件委托:利用事件冒泡的原理,将子元素的事件委托给父元素执行。
-
事件对象下面的属性:
target:获取当前操作的元素对象。兼容问题:srcElement
-
var oUl = document.querySelector('ul'); oUl.onclick = function (ev) { var ev = ev || window.event; var element = ev.target || ev.srcElement;//获取当前操作的元素对象 alert(element.innerHTML); }
for...in迭代和for...of的区别+forEach
-
for … in循环遍历的是对象的属性名称。
var a = ['A', 'B', 'C']; a.name = 'Hello'; for (var x in a) { alert(x); // '0', '1', '2', 'name' } -
for … of循环只循环集合本身的元素(无法遍历对象)
var a = ['A', 'B', 'C']; a.name = 'Hello'; for (var x of a) { alert(x); // 'A', 'B', 'C' } -
forEach方法
var a = ['A', 'B', 'C']; a.forEach(function (element, index, array) { // element: 指向当前元素的值 // index: 指向当前索引 // array: 指向Array对象本身 alert(element); });
数组去重
-
利用ES6 set + 解构赋值
let arr = [1, 2, 2, 3, 3, 3, 4, 4, 4, 5, 6, 6, 7, 8, 8, 9, 9, 9, 9] console.log([...new Set(arr)]) -
indexOf
-
利用对象的键值对唯一
var arr = [1, 2, 3, 2, 3, 4, 5, 6, 7, 8, 9, 8, 5]; //将数组转换成对象 //利用对象的key值不能重复这一特性 var toObject = function (array) { var obj = {}; for (var i = 0, j = array.length; i < j; i++) { obj[array[i]] = true; } return obj; } //再将对象转换成数组 var toArray = function (obj) { var arr = []; for (var i in obj) { arr.push(i); } return arr; } var uiq = function (arr) { return toArray(toObject(arr)); } var arr1 = uiq(arr); console.log(arr1);
数组扁平化
-
reduce
function flatten(arr) { return arr.reduce((result, item)=> { return result.concat(Array.isArray(item) ? flatten(item) : item); }, []); }reduce是数组的一种方法,它接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。
reduce包含两个参数:回调函数,传给total的初始值
-
toString & split
function flatten(arr) { return arr.toString().split(',').map(function(item) { return Number(item); }) } -
join & split
function flatten(arr) { return arr.join(',').split(',').map(function(item) { return parseInt(item); }) } -
递归
function flatten(arr) { var res = []; arr.map(item => { if(Array.isArray(item)) { res = res.concat(flatten(item)); } else { res.push(item); } }); return res; } -
扩展运算符
function flatten(arr) { while(arr.some(item=>Array.isArray(item))) { arr = [].concat(...arr); } return arr; }