03-JS高阶:函数、继承、内置对象

1.函数内部的this指向

这些 this 的指向,是当我们调用函数的时候确定的。调用方式的不同决定了this 的指向不同

一般指向我们的调用者.

序号调用方式this指向
1普通函数调用window
2对象方法调用该方法所属的对象
3构造函数调用实例对象,原型对象的方法也指向实例对象
4事件绑定的方法事件的绑定者
5定时器函数window
6立即执行函数window

2.函数对象的原型的方法

2.1 Function.prototype.call()---call()方法

call():使用一个指定的 this 值调用一个函数(简单理解为调用函数的方式,但是它可以改变函数的 this 指向)

 call(thisObj, arg1, arg2...)
var o = {
    name: '小谷'
}
 function fn(a, b) {
      console.log(this);
      console.log(a+b)
};
fn(1,2)// 此时的this指向的是window 运行结果为3
fn.call(o,1,2)//此时的this指向的是对象o,参数使用逗号隔开,运行结果为3

2.2 Function.prototype.apply()---apply()方法

apply() 方法调用一个函数。简单理解为调用函数的方式,但是它可以改变函数的 this 指向。

apply(thisObj, [argArray])

应用场景: 经常跟数组有关系

var o = {
    name: '小好'
}
 function fn(a, b) {
      console.log(this);
      console.log(a+b)
};
fn()// 此时的this指向的是window 运行结果为3
fn.apply(o,[1,2])//此时的this指向的是对象o,参数使用数组传递 运行结果为3

2.3 Function.prototype.bind()---bind()方法

bind() 方法不会调用函数,但是能改变函数内部this 指向,返回的是原函数改变this之后产生的新函数

 bind(thisObj,arg1,arg2,...)

如果只是想改变 this 指向,并且不想调用这个函数的时候,可以使用bind

应用场景:不调用函数,但是还想改变this指向

 var o = {
 name: '小谷'
 };
​
function fn(a, b) {
    console.log(this);
    console.log(a + b);
};
var f = fn.bind(o, 1, 2); //此处的f是bind返回的新函数
f();//调用新函数  this指向的是对象o 参数使用逗号隔开

2.4 call、apply、bind三者的异同

  • 共同点 : 都可以改变this指向

  • 不同点:

    • call 和 apply会立即调用函数.bind不会立即调用函数, 需要手动调用.

    • call及bind 和 apply传递的参数不一样,call及bind传递参数使用逗号隔开,apply使用数组传递.

  • 应用场景

    1. call经常用作判断数据类型和继承.

    2. apply 经常跟数组有关系. 比如借助于数学对象实现数组最大值最小值

    3. bind不调用函数,但是还想改变this指向. 比如改变定时器内部的this指向.

2.5 Object.prototype.toString()判断数据类型

toString()是Object的原型方法,调用该方法,返回 "[object type]",其中 type 是对象的类型。这是一个内部属性,其格式为[object Xxx],其中Xxx就是对象的类型。

对于Object对象,直接调用toString()就能返回[object Object],而对于其他对象,则需要通过call、apply来调用才能返回正确的类型信息。

var toString = Object.prototype.toString;
​
toString.call(123); //"[object Number]"
toString.call('abcdef'); //"[object String]"
toString.call(true); //"[object Boolean]"
toString.call([1, 2, 3, 4]); //"[object Array]"
toString.call({name:'wenzi', age:25}); //"[object Object]"
toString.call(function(){ console.log('this is function'); }); //"[object Function]"
toString.call(undefined); //"[object Undefined]"
toString.call(null); //"[object Null]"
toString.call(new Date()); //"[object Date]"
toString.call(/^[a-zA-Z]{5,20}$/); //"[object RegExp]"
toString.call(new Error()); //"[object Error]"

2.6 constructor来判断数据的类型

我们可以通过constructor来判断数据的类型,但是除了null、undefined,因为他们不是由对象构建。

数字、布尔值、字符串是包装类对象,所以有constructor

var num = 10;
var conNaN = NaN;
var str = '小好';
var flag = true;
var conNull = null;
var conUndefined;
var arr = [1, 2, 3];
var obj = {
    name: '小谷'
};
​
function fun1() {
    console.log('函数');
}
var date = new Date();
var reg = /zml/;
console.log(num.constructor);
console.log(conNaN.constructor);
console.log(str.constructor);
console.log(flag.constructor);
// 没有constructor会报错
// console.log(conNull.constructor);
// console.log(conUndefined.constructor);
console.dir(Array);
console.dir(arr);
//返回true
console.log(arr.constructor === Array);

3. JS继承的实现方式

3.1 构造函数继承

  1. 先定义一个父构造函数

  2. 再定义一个子构造函数

  3. 子构造函数继承父构造函数的属性(使用call方法)

 // 1. 父构造函数
 function Father(uname) {
   // this 指向父构造函数的对象实例
   this.uname = uname;
 }
  // 2 .子构造函数 
function Son(uname, age) {
  // this 指向子构造函数的对象实例
  //3.使用call方式实现子继承父的属性
  Father.call(this, uname);
  this.age = age;
}
var son = new Son('小好', 18);
console.log(son);

3.2 原型对象继承方法

  1. 先定义一个父构造函数

  2. 再定义一个子构造函数

  3. 子构造函数继承父构造函数的属性(使用call方法)

  4. 设置子级的prototype原型对象

// 1. 父构造函数
function Father(uname, age) {
  // this 指向父构造函数的对象实例
  this.uname = uname;
  this.age = age;
}
Father.prototype.money = function() {
  console.log(100000);
 };
 // 2 .子构造函数 
  function Son(uname, age, score) {
      // this 指向子构造函数的对象实例
      Father.call(this, uname, age);
      this.score = score;
  }
// Son.prototype = Father.prototype;  这样直接赋值会有问题,如果修改了子原型对象,父原型对象也会跟着一起变化
  Son.prototype = new Father();
  // 如果利用对象的形式修改了原型对象,别忘了利用constructor 指回原来的构造函数
  Son.prototype.constructor = Son;
  // 这个是子构造函数专门的方法
  Son.prototype.exam = function() {
    console.log('孩子要考试');
​
  }
  var son = new Son('小好', 18, 100);
  console.log(son);

3.3 Object.create实现继承

Object.create(proto, [propertiesObject])
  • 方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。返回在指定原型对象上添加新属性后的对象。

  • proto:新创建对象的原型对象。

  • propertiesObject:可选。需要传入一个对象,该对象的属性类型参照Object.defineProperties()的第二个参数。如果该参数被指定且不为 undefined,该传入对象的自有可枚举属性(即其自身定义的属性,而不是其原型链上的枚举属性)将为新创建的对象添加指定的属性值和对应的属性描述符。

4.内置对象Array的操作方法

4.1 数组方法forEach遍历数组

//forEach遍历数组 
arr.forEach(function(value, index, array) {
       //参数一是:数组元素
       //参数二是:数组元素的索引
       //参数三是:当前的数组
 })
  //相当于数组遍历的 for循环 没有返回值

4.2 数组方法map遍历数组

map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。

map() 方法按照原始数组元素顺序依次处理元素。

注意: map() 不会对空数组进行检测

var arr = [1,2,3,4,5,6,7];
var newArr = arr.map(function(value, index, array){
    //参数一是:数组元素
    //参数二是:数组元素的索引
    //参数三是:当前的数组
    return value*4;
});
console.log(arr);//[1,2,3,4,5,6,7]
console.log(newArr);//[4,8,12,16,20,24,28]

4.3 数组方法filter过滤数组

filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。

  var arr = [12, 66, 4, 88, 3, 7];
  var newArr = arr.filter(function(value, index,array) {
     //参数一是:数组元素
     //参数二是:数组元素的索引
     //参数三是:当前的数组
     return value >= 20;
  });
  console.log(newArr);//[66,88] //返回值是一个新数组

4.4 数组方法some

some 查找数组中是否有满足条件的元素 ,如果数组中有元素满足条件返回 true,否则返回 false。

 var arr = [10, 30, 4];
 var flag = arr.some(function(value,index,array) {
    //参数一是:数组元素
     //参数二是:数组元素的索引
     //参数三是:当前的数组
     return value < 3;
  });
console.log(flag);//false返回值是布尔值,只要查找到满足条件的一个元素就立马终止循环

4.5数组方法every

every() 方法用于检测数组所有元素是否都符合指定条件(通过函数提供)。

every() 方法使用指定函数检测数组中的所有元素:

array.every(function(value,index,array))
  • 如果数组中检测到有一个元素不满足,则整个表达式返回 false ,且剩余的元素不会再进行检测。

  • 如果所有元素都满足条件,则返回 true。

    注意: every() 不会对空数组进行检测。

    注意: every() 不会改变原始数组。

4.6 数组方法find

find() 方法返回通过测试(函数内判断)的数组的第一个元素的值。

find() 方法为数组中的每个元素都调用一次函数执行:

array.find(function(value,index,array){})
  • 当数组中的元素在测试条件时返回 true 时, find() 返回符合条件的元素,之后的值不会再调用执行函数。

  • 如果没有符合条件的元素返回 undefined

4.7 数组方法reduce

reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。

array.reduce(function(total,value,index,array){},initialValue)
  • total 必需。初始值, 或者计算结束后的返回值。 value 必需。当前元素 index 可选。当前元素的索引 array可选。当前元素所属的数组对象。

  • initialValue 作为第一次调用 callback函数时的第一个参数的值。 如果没有提供初始值,则将使用数组中的第一个元素。

  • 返回值:最终计算的一个值

  • 14
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值