2020-12-30-继承和函数的进阶2
作者:zhzh
时间: 2020-12-30
书籍/博客/视频:
网站地址:
摘要
js的预解析知识的回顾,
this的指向的理解
总结
知道了函数的声明和表达式在js中执行的顺序,知道了call、apply和bind的用法 ,和区分了三个的区别和作用,重写了冒泡排序
目录
9、函数声明和函数表达式
//1、函数声明
fn();
function fn() {
console.log('test');
}
//2、函数表达式
fn2();
var fn2 = function () {
console.log('test2');
}
输出结果:
通过JavaScript的预解析
function fn() {
console.log('test');
}
fn();
var fn2;
fn2();
fn2 = function(){
console.log('test2');
}
应为这里的 fn2 虽然已经声明过了,但是此时的fn2 的值是undefined,所以,fn2无法当函数去引用。
//函数表达式不会进行函数的提升
//3、根据条件声明函数
if(true){
function fn() {
console.log('fn - true');
}
}
else {
function fn() {
console.log('fn - false');
}
}
fn();
现在的浏览器输出的结果:‘fn - true’;
IE 8 之前的输出的是:‘fn - false’;
现在的高版本浏览器 不会提升if语句中的函数声明,但老版本的会提升。
*** 解决兼容性问题 ***
使用函数的表达式的方法解决兼容性问题
var fn;
if (true){
fn = function{
console.log('fn - true');
}
}else{
fn = function{
console.log('fn - false');
}
}
fn();
11、 函数的调用形式和this的指向
// 1、普通函数调用
function fn() {
console.log(this);//this指向的是window
}
fn();
// 2 方法调用
var obj = {
fn: function () {
console.log(this);//指向obj
}
}
obj.fn();
// 3作为构造函数调用
// 构造函数指向由该构造函数创建的对象
// 4、作为事件处理函数
// btn.onclick = function(){
// console.log(this);
// }//指向的是btn
// 5、作为定时器的参数
setInterval(function () {
console.log(this);//指向window
},1000)
function fn() {
console.log(this);
}
var obj = {
name : 'zs',
fn : fn
}
obj.fn();
输出的结果:指向的是object
总结:函数内部的this,是由函数调用的时候来确定他的指向的
12,13,14,15 call、apply和bind
1、call的应用
通过直接添加的方式实现在object中添加属性
var obj = {
0:100,
1:10,
2:11,
3:20,
length:4
};
obj['4'] = 30;
obj.length++
console.dir(obj);
通过call来改变,数组原型方法的this指向来实现,在伪数组中使用数组的原型方法
var obj = {
0:100,
1:10,
2:11,
3:20,
length:4
};
//这里的0,1,2,3,length不是索引,而是属性
Array.prototype.push.call(obj,30);
console.dir(obj);
2、apply的应用
apply的第二个参数是数组;
常用的地方是把数组展开
//求数组中的最大值
var arr = [5,10,1,3,6];
Max = Math.max.apply(null,arr);//apply会把数组展开,返回给math,//这里的this指向的是Math,所以可以传入一个null
console.log(Max);
//遍历出数组中的值(把数组展开)
var arr = [5,10,1,3,6];
console.log.apply(console,arr);
3、bind的应用
bind()方法主要就是将函数绑定到某个对象,bind()会创建一个函数,函数体内的this对象的值会被绑定到传入bind()中的第一个参数的值
var obj = {
name: 'zs',
fun: function () {
setInterval(function () {
console.log(this.name);//这里this指向的是window所以打印出来的this.name是空的
}.bind(this),1000);//这里改变了this的指向,把this指向了obj
}
}
obj.fun();
16、 函数中的其他成员
函数中有4个属性:
1、arguments 伪数组 获取到的是函数的实参.
2、caller 是函数的调用者,在全局范围调用的时候
3、name 是函数的名称
4、length 是函数形参的个数
函数中存在一个私有变量 arguments:和函数中的arguments的属性是一样的
arguments的示例:
通过函数中的argument来遍历数组,选出最大值
function Max() {
// console.log(arguments);
//当函数的参数不是固定的时候我们可以用argument来获取
//在函数内部可以获取到传过来的参数
var max = arguments[0];
for (var i = 0;i<arguments.length;i++){
if (max < arguments[i]){
max = arguments[i];
}
}
// var max2 = Math.max.apply(null,arguments);
return max;
}
console.log(Max(1,2,5));
17、18、高阶函数 — 函数作为参数 及其 sort 案例
1、函数作为参数:
function eat(fn) {
setTimeout(function () {
console.log('吃完饭');
//吃完之后
fn();
},2000)
}
//函数作为参数传入eat中
eat(function () {
console.log('我们去唱歌');
});
函数作为参数的案例:
sort排序
重写冒泡排序,把两数差放到了函数外面,用函数分装起来,通过吧函数作为参数传回原函数中
//冒泡排序
Array.prototype.mySort = function (fn) {
for (var i = 0;i < this.length-1;i++){
var isSort = true;//假设排好序
for (var j = 0;j < this.length - i - 1;j++){
if (fn(this[j],this[j+1]) > 0){//这里传入一个两数差的值和零做比较
isSort = false;
var temp = this[j];
this[j] = this[j+1];
this[j+1] = temp;
}
}
if (isSort){
break;
}
}
}
var arr = [35,1,6,20];
arr.mySort(function (a,b) {
return b - a;
})
console.log(arr);
//输出:
0: 35
1: 20
2: 6
3: 1
19高阶函数—函数作为返回值的时候
案例1:生成随机数
写一个函数,生成 1-10 之间的随机整数
第一调用生成随机数,以后每次调用都返回一个随机值
function getRandom() {
var random = parseInt(Math.random()*10) + 1;
return function () {
return random;
}
}
var fn = getRandom();//先调用了一次函数//这里返回的是之前返回的函数,所以fn是函数
console.log(fn());//回过头去调用fn,返回随机数
console.log(fn());
console.log(fn());
案例2:两数相加,一个固定的数加上另外一个任意的数m
100 + m
1000 + m
10000 + m
function getFun(n){
return function (m) {
return n + m;
}
}
//求 100 + m
var fn100 = getFun(100);//先调用了getFun函数传入了n,返回的是一个 100 + m 的一个函数
console.log(fn100(2));//传入了m的值,返回102(100+2)
//求 1000 + m
var fn1000 = getFun(1000);
console.log(fn1000(2))
数
console.log(fn());
console.log(fn());
案例2:两数相加,一个固定的数加上另外一个任意的数m
100 + m
1000 + m
10000 + m
function getFun(n){
return function (m) {
return n + m;
}
}
//求 100 + m
var fn100 = getFun(100);//先调用了getFun函数传入了n,返回的是一个 100 + m 的一个函数
console.log(fn100(2));//传入了m的值,返回102(100+2)
//求 1000 + m
var fn1000 = getFun(1000);
console.log(fn1000(2))