Contents
  1. 1. 函数的四种调用模式
    1. 1.1. 1、普通函数执行
    2. 1.2. 2. 方法调用模式
    3. 1.3. 3. 构造函数模式
    4. 1.4. 4. call/apply(上下文)模式
    5. 1.5. 5. 上下文模式的应用
    6. 1.6. 6. 数组去重

函数的四种调用模式

1、普通函数执行

  • this -> window
  • 声明一个函数后,就直接调用
    code block
    1
    2
    3
    4
    5
    function foo() {
    console.log(1);
    console.log(this === window);//true
    }
    foo();

2. 方法调用模式

  • this —> 该方法的调用者
  • 通过一个对象来调用方法

    1
    2
    3
    4
    5
    6
    7
    var obj = {
    sayHi: function() {
    console.log("hello, girl.");
    console.log(this === obj);//true
    }
    };
    obj.sayHi();

3. 构造函数模式

  • this -> 当前创建出来的对象
  • 配合new操作符 来 调用函数

    1
    2
    3
    4
    5
    6
    7
    function fn(name, age, gender) {
    this.name = name;
    this.age = age;
    this.gender = gender;
    console.log(this);
    }
    var f = new fn('f');

4. call/apply(上下文)模式

  • this -> 用户动态指定的
    • 指定call or apply 方法的第一个参数
  • 区别:
    • .call(thisObj, arg1, arg2, …,argN):thisObj为 this的指向。之后为形参列表,就是fn在执行时的实参列表
    • .apply(thisObj, [实参]): thisObj 为 this的指向,数组参数为 fn在执行时的实参
  • 注意:在非严格模式下,如果thisObj 赋值为 null 或者不传实参,此时this -> window 对象,就相当于 普通函数执行模式。

    1
    2
    3
    4
    var o = {};
    fn.call(o, 'o', 18, 'man');
    fn.apply( o, ['o', 18, 'man'] );
    console.log(o);

5. 上下文模式的应用

+ 1 数组的合并
1
2
3
4
var arr1 = [1, 2, 3];
var arr2 = [4, 5 ,6];
Array.prototype.push.apply(arr1, arr2);
console.log(arr1);
+ 2 借调方法(函数)
- 借用原生方法
      + 求数组中的最大值
      + 获取内置对象类型
      + 将伪数组变成真数组
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// a:借用构造函数
function parent(name,age,gender){
this.name=name;
this.age=age;
this.gender=gender;
}
function child(name, age, gender, address) {
parent.call(this, name, age, gender);
this.address = address;
}
var c = new child('c', 19, 'nicai', 'yueqiu');
console.log(c);
// b: 借调原生方法
var data = [67, 89, 190, 23, 10, 100];
// 求data中的最大值
var max = Math.max.apply(null, data);
console.log(max); // 100
// c: 获取内置对象类型
console.log(typeof 1);
console.log(typeof []); // "array"
console.log(typeof new Date); //"date"
// 功能:如果是内置对象,返回其类型名;eg. [] -> "array", 1 -> "number"
// 如果是自定义对象,就返回"object".
function getType(obj) {
// return Object.prototype.toString.call(obj).slice(8, -1).toLowerCase();
// var patt = /^\[\w+ (\w+)\]$/;
var patt = /^\[object (\w+)\]$/;
var str = Object.prototype.toString.call(obj);
var match = patt.exec(str);
return match[1].toLowerCase();
}
console.log(getType(/a/));
- 借用原生方法
  + 求数组中的最大值
  + 获取内置对象类型
  + 将伪数组变成真数组

6. 数组去重

  • 实现思路:
    • 声明一个函数实现数组去重,取名为unique;
    • 判断浏览器是否支持数组的indexOf方法
    • 如果不支持,就自己实现数组的indexOf方法,并且将其扩展到数组的原型对象上。
    • 遍历数组,首先判断结果数组ret中是否含有当前遍历到的元素,
    • 如果没有,就将当前元素添加到ret中。
    • 循环结束,将ret返回。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
var arr = [1, 2, 2 , '1'];
// indexOf
function unique(a) {
var ret = [];
// 如果不支持indexOf方法
// 自己实现数组的indexOf方法,并添加到数组的原型对象上。
if( !ret.indexOf ){
Array.prototype.indexOf = function(val) {
// this指向的就是 indexOf的调用者 (数组对象)
// 如果循环顺利执行完,就表示没有val值,返回-1;
// 否则返回val在当前数组中的下标值。
for(var i = 0,l = this.length; i < l; i++){
if(this[i] === val) return i;
}
return -1;
};
}
for(var i = 0,l = a.length;i < l; i++){
// 如果ret中不存在当前遍历到的元素,就添加到ret中
// 否则就不要添加
if( ret.indexOf(a[i]) === -1 ){
ret.push(a[i]);
}
}
return ret;
}
console.log(unique(arr));
Contents
  1. 1. 函数的四种调用模式
    1. 1.1. 1、普通函数执行
    2. 1.2. 2. 方法调用模式
    3. 1.3. 3. 构造函数模式
    4. 1.4. 4. call/apply(上下文)模式
    5. 1.5. 5. 上下文模式的应用
    6. 1.6. 6. 数组去重