> For the complete documentation index, see [llms.txt](https://note.niefee.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://note.niefee.com/directory/mian-xiang-dui-xiang-bian-cheng.md).

# 面向对象编程

* [面向对象编程](https://note.niefee.com/directory/pages/-LjTb6emmGmzUu7RhpnX#面向对象编程)
  * [构造函数](https://note.niefee.com/directory/pages/-LjTb6emmGmzUu7RhpnX#构造函数)
    * [prototype属性](https://note.niefee.com/directory/pages/-LjTb6emmGmzUu7RhpnX#prototype属性)
  * [call与apply](https://note.niefee.com/directory/pages/-LjTb6emmGmzUu7RhpnX#call与apply)
  * [bind()](/directory/mian-xiang-dui-xiang-bian-cheng.md#bind)
  * [this的用法](https://note.niefee.com/directory/pages/-LjTb6emmGmzUu7RhpnX#this的用法)

## 面向对象编程

### 构造函数

所谓"`构造函数`"，其实就是一个普通函数，但是内部使用了`this`变量。 构造函数使用`new`生成实例对象，`this`变量会绑定在实例对象上。

```javascript
function Cat(name,color){
    //nameFn会是生成的实例对象的属性
　　　　this.nameFn=name;
　　　　this.colorFn=color;
　　}

var cat1=new Cat('大毛','黑色');

cat1.nameFn//大毛

//constructor属性会指向构造函数
cat1.constructor == Cat;//true

//验证一个实例对象的原型
cat1 instanceof Cat;//true
```

#### prototype属性

每个构造函数的`prototype`属性指向一个对象，实例会继承所有的属性与方法。

```javascript
Cat.prototype.say = function(){console.log("喵喵..")};

cat1.say();//喵喵..
```

`hasOwnProperty()`

用来判断某一个属性到底是本地属性，还是继承自`prototype`对象的属性。

`in` 判断某个实例是否含有某个属性，不管是不是本地属性。

### call与apply

```javascript
obj.call(thisObj, arg1, arg2, ...);
obj.apply(thisObj, [arg1, arg2, ...]);
```

两者作用一致，都是把`obj`(即`this`)绑定到`thisObj`，这时候`thisObj`具备了`obj`的**属性**和**方法**。或者说`thisObj`『**继承**』了`obj`的属性和方法。

也可以当成，把`obj`上的方法，放到`thisObj`上执行。

> bind()与call()相似，但不会立即执行。
>
> > 参数是null或者undefined，等于将this绑定到全局对象。
>
> [参考1](http://www.ruanyifeng.com/blog/2010/05/object-oriented_javascript_encapsulation.html) [参考2](http://www.ruanyifeng.com/blog/2011/06/designing_ideas_of_inheritance_mechanism_in_javascript.html)

### bind()

`bind()`方法会创建并返回一个新函数，称为绑定函数。

当调用这个绑定函数时，绑定函数会以创建它时传入 `bind()`方法的第一个参数作为 `this`，传入 `bind()` 方法的第二个以及以后的参数加上绑定函数运行时本身的参数按照顺序作为原函数的参数来调用原函数。

```javascript
this.num = 9;  
var mymodule = {  
  num: 81,
  getNum: function() { return this.num; }
};

mymodule.getNum(); // 81

var getNum = mymodule.getNum;  
getNum(); // 9, 因为在这个例子中，"this"指向全局对象

// 创建一个'this'绑定到module的函数
var boundGetNum = getNum.bind(module);  
boundGetNum(); // 81
```

`bind()`函数可以使用预设的初始参数。

```javascript
function list() {
  return Array.prototype.slice.call(arguments);
}

var list1 = list(1, 2, 3); // [1, 2, 3]

// 创建函数并给函数预设的打头参数
var leadingThirtysevenList = list.bind(undefined, 37);

var list2 = leadingThirtysevenList(); // [37]
var list3 = leadingThirtysevenList(1, 2, 3); // [37, 1, 2, 3]
```

### this的用法

随着`this`的使用场合，`this`的值会发生变化。 总共有四种方式：

* 纯粹的函数调用

函数体内调用`this`，代表全局对象`Global`。

```javascript
var x = 1;
function test(){
　　this.x = 0;
}
test();
alert(x); //0
```

* 作为对象的方法调用

函数还可以作为某个对象的方法调用，这时this就指这个上级对象。

```javascript
var obj={
    x:10,
    fn:function () {
        console.log(this.x);
    }
}
obj.fn();//10
```

* 作为构造函数调用

所谓构造函数，就是通过这个函数生成一个新对象（`object`）。这时，`this`就指这个新对象。

```javascript
var x=10;
function test() {
    console.log(this.x);//undefined
    this.x=5;
    console.log(this.x);//5
}
var o=new test();
console.log(x);//10
console.log(o.x);//5
```

* apply调用

`apply()`是函数对象的一个方法，用来改变函数的调用对象。`this`指的就是这个参数。

```javascript
    var x = 0;
　　function test(){
　　　　alert(this.x);
　　}
　　var o={};
　　o.x = 1;
　　o.m = test;
　　o.m.apply(); //0，函数调用时的变量环境是定义时的环境
　　o.m.apply(o); //1，this代表对象o
```

`apply()`的参数为空时，默认调用全局对象。因此，这时的运行结果为`0`，证明`this`指的是全局对象。

> [参考](http://www.ruanyifeng.com/blog/2010/04/using_this_keyword_in_javascript.html)
