# 面向对象 - call

函数实例的 `call` 方法，可以指定函数内部 `this` 的指向（即函数执行时所在的作用域），然后在所指定的作用域中，调用该函数

```javascript
var obj = {}

var f = function () {
  return this
}

f() === window // true
f.call(obj) === obj // true

```

上面代码中，全局环境运行函数 `f` 时，`this` 指向全局环境（浏览器为 `window` 对象）； `call` 方法可以改变 `this` 指向，指定 `this` 指向对象 `obj`，然后在对象 `obj` 的作用域中运行函数 `f`&#x20;

call 方法的参数，应该是一个对象。如果参数为空、`null` 和 `undefined`，则默认传入全局对象

```javascript
var n = 123
var obj = { n: 456 }

function a() {
  console.log(this.n)
}

a.call() // 123
a.call(null) // 123
a.call(undefined) // 123
a.call(window) // 123
a.call(obj) // 456

```

上面代码中，`a` 函数中的 `this` 关键字，如果指向全局对象，返回结果为 `123`。如果使用 `call` 方法将 `this` 关键字指向 `obj` 对象，返回结果为 `456`。可以看到，如果 `call` 方法没有参数，或者参数为 `null` 或 `undefined`，则等同于指向全局对象

如果 `call` 方法的参数是一个原始值，那么这个原始值会自动转成对应的包装对象，然后传入 `call` 方法

```javascript
var f = function () {
  return this
}

f.call(5)

// Number {[[PrimitiveValue]]: 5}
```

上面代码中，`call` 的参数为 `5`，不是对象，会被自动转成包装对象（`Number` 的实例），绑定 `f` 内部的 `this`

`call` 方法还可以接受多个参数

```javascript
func.call(thisValue, arg1, arg2, ...)
```

call 的第一个参数就是 this 所要指向的那个对象，后面的参数则是函数调用时所需的参数

```javascript
function add(a, b) {
  return a + b
}

add.call(this, 1, 2) // 3
```

上面代码中，`call` 方法指定函数 `add` 内部的 `this` 绑定当前环境（对象），并且参数为 `1` 和 `2`，因此函数 `add` 运行后得到 `3`

`call` 方法的一个应用是调用对象的原生方法

```javascript
var obj = {}
obj.hasOwnProperty('toString') // false

// 覆盖掉继承的 hasPwnProperty 方法
obj.hasOwnProperty = function () {
  return true
}
obj.hasOwnProperty('toString') // true

Object.prototype.hasOwnProperty.call(obj, 'toString') // false
```

上面代码中，`hasOwnProperty` 是 `obj`  对象继承的方法，如果这个方法一旦被覆盖，就不会得到正确结果。`call` 方法可以解决这个问题，它将 `hasOwnProperty` 方法的原始定义放在 `obj` 对象上执行，这样无论 `obj` 上有没有同名方法，都不会影响结果


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://yyaozhibo.gitbook.io/qian-duan-xue-xi/js/mian-xiang-dui-xiang-call.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
