call、apply和bind区别
call和apply都是function原型上的方法,每一个函数作为function的实例,可以调用call和apply方法都是用来改变函数中this的指向问题的唯一的区别就是传给函数参数时,call时一个个传参,apply是以数组形式,bind也是改变函数指向不过bind不会把函数立即执行,而是预先处理this,bind 方法的返回值是函数,需要手动调用才会执行,而 apply 和 call 则是立即调用。三个以内,call和apply性能差不多,但是三个以上,call性能更好一点(解析数组比较消耗资源)
测试性能
1.自己写的测试只供参考:因为任何代码的性能都是和测试的环境有关的例如的cpu、内存、GPU、在电脑当前的性能是不同的,同时不同浏览器的性能也是不一样的
2.let t1=new Date() for(var i=0;i<100000;i++){} console.log(new Date()-t1);
3.使用console.time('你要检测的那个')
记住要使用console.timeEnd()
结尾
4.可以在火狐浏览器上安装FireBug,使用console.profile()
可以精确的获取到程序每一个步骤的消耗时间
call,apply、bind原生js实现
每个javascript函数其实都是function对象,而function对象其实是构造函数,构造函数有自己的原型对象,function.prototype,call、apply、bind就是他的原型对象上面的方法
call
分析
person.call(egg)其实就是相当于在egg里面添加了一个person函数这样函数的this就会指向调用它的对象也就是egg
var egg = {
name: "张三",
person() {
console.log(this.name);
}
}
egg.person();//张三
代码实现(es6)
function person(a, b, c, d) {
return {
// console.log(this.name);
// console.log(a,b,c,d);
name: this.name,
a: a,
b: b,
c: c,
d: d
}
}
var egg = {
name: '张三'
}
Function.prototype.newCall = function (obj) {
var obj = obj || window
obj.p = this
var newArguments = []
for (var i = 1; i < arguments.length; i++) {
newArguments.push(arguments[i])
}
// console.log(newArguments);
var result = obj.p(...newArguments)
delete obj.p
return result
}
var bili = person.newCall(egg, "梦", "大好人", "帅", "大坏蛋")
console.log(bili);
person.newCall(null, "梦", "大好人", "帅", "大坏蛋")
person.newCall(egg, "梦", "大好人", "帅", "大坏蛋")
代码实现(es5)
apply
分析
同上
代码实现(es6)
function person(a, b, c, d) {
return {
// console.log(this.name);
// console.log(a,b,c,d);
name: this.name,
a: a,
b: b,
c: c,
d: d
}
}
var egg = {
name: '张三'
}
Function.prototype.newApply = function (obj, arr) {
var obj = obj || window
obj.p = this
if (!arr) {
obj.p()
} else {
var newArguments = []
for (var i = 0; i < arr.length; i++) {
newArguments.push(arr[i])
}
var result = obj.p(...newArguments)}
delete obj.p
return result
}
var bili = person.newApply(egg, ["梦", "大好人", "帅", "大坏蛋"])
console.log(bili);
person.newApply(null, ["梦", "大好人", "帅", "大坏蛋"])
person.newApply(egg, ["梦", "大好人", "帅", "大坏蛋"])
代码实现(es5)
bind
分析
bind返回一个函数,函数里面有函数的,这样容易造成this的丢失所以用that先保存一下
代码实现(es6)
翻了好多博客,觉得不是很重要就不写了
请用代码实现(5).add(3).minus(6)=2
分析
首先进行一个链式操作也就是说在add过后直接可以调用一个方法说明是返回了一个数字,于是返回值里面都是数字,对输入的也需要做个转换,Number是基于浏览器底层原理实现的强转换,最后将这两种方法添加道原型上1和2都可以2,比较简单,eval()是es1里面的
(function () {
function check(n) {
// n = Number(n)
// return isNaN(n) ? 0 : n
//赋值操作永远成立,前面为true接着往下执行判断,但是这种存在问题会让字符串三不变化
// return n=Number(n)&&(isNaN(n)?0:n)
}
function add(n) {
n = check(n)
return this + n
}
function minus(n) {
n = check(n)
return this - n
}
//1. Number.prototype.add = add
// Number.prototype.minus = minus
//2.
["add","minus"].forEach(item=>{
Number.prototype[item]=eval(item)
})
})()
箭头函数和普通函数的区别
箭头函数与普通函数的区别:
1.箭头函数书写起来比较简单(如果箭头函数只有一个参数那么小括号可以省略,如果箭头函数只有一行return+简单的语句那么可以把return和{省略掉)
2.箭头函数没有this(它的this永远都是上下文执行的this,并且没法通过call、apply、bind来进行this的更改)
3.箭头函数没有argument(类似数组的结构)只能基于…args获取传递的参数集合(数组)
4.箭头函数不能被new执行,因为它不存在prototype
注意:这个sort不是调用的sort方法而是,而是自己写进一个函数这个是回调函数,回调函数this一般都是window,如果是sort则this是arr
jq 中each的思想
怎么实现大小写转换
分析
1.怎么找到那些是字母首先要找到,①可以使用正则表达式,②可以for遍历,但是效率太低了
2.每个字母都需要拿到,遍历数组
3.怎么看哪些是大写哪些是小写①ascII码(可以调用charCodeAt②如果变成大写后和自己一样就说明原理也是大写
代码实现
let str = "加油!YOU会success的,1000"
str = str.replace(/[a-zA-Z]/g, content => {
return content.toUpperCase() === content?content.toLowerCase():content.toUpperCase()
})
console.log(str);
let str = "加油!YOU会success的,1000"
str = str.replace(/[a-zA-Z]/g, content => {
if(content.charCodeAt()>=65 && content.charCodeAt()<=90){
return content.toLowerCase();
}
else{
return content.toUpperCase()
}
})
console.log(str);