032. js get,set - cwy007/tips-and-skills GitHub Wiki

1. 取值函数 get,存值函数 set

var o = Object.defineProperties({}, {
  p1: { value: 123, enumerable: true },
  p2: { value: 'abc', enumerable: true },
  p3: { get: function () { return this.p1 + this.p2 },
    enumerable:true,
    configurable:true
  }
});

o.p1 // 123
o.p2 // "abc"
o.p3 // "123abc"

上面代码中的p3属性,定义了取值函数get。这时需要注意的是,一旦定义了取值函数get(或存值函数set),就不能将writable设为true,或者同时定义value属性,会报错

存取器(accessor) 除了直接定义以外,属性还可以用存取器(accessor)定义。其中,存值函数称为setter,使用set命令;取值函数称为getter,使用get命令。

2. 一些术语

  1. property 属性
  2. window 指的是浏览器的顶层对象
  3. 系统原生的属性(即非用户自定义的属性)
  4. 事件,回调函数

3. 继承

new命令简化的内部流程,可以用下面的代码表示。

  // 创建一个空对象,继承构造函数的 prototype 属性
  var context = Object.create(constructor.prototype);
function _new(/* 构造函数 */ constructor, /* 构造函数参数 */ param1) {
  // 将 arguments 对象转为数组
  var args = [].slice.call(arguments);
  // 取出构造函数
  var constructor = args.shift();
  // 创建一个空对象,继承构造函数的 prototype 属性
  var context = Object.create(constructor.prototype);
  // 执行构造函数
  var result = constructor.apply(context, args);
  // 如果返回结果是对象,就直接返回,否则返回 context 对象
  return (typeof result === 'object' && result != null) ? result : context;
}

// 实例
var actor = _new(Person, '张三', 28);

link: http://javascript.ruanyifeng.com/stdlib/attributes.html

4. this

总结一下,JavaScript 语言之中,一切皆对象,运行环境也是对象,所以函数都是在某个对象之中运行,this就是这个对象(环境)

var o = {
  v: 'hello',
  p: [ 'a1', 'a2' ],
  f: function f() {
    this.p.forEach(function (item) {
      console.log(this.v + ' ' + item);
    });
  }
}

o.f()
// undefined a1
// undefined a2

上面代码中,foreach方法的回调函数中的this,其实是指向window对象,因此取不到o.v的值。 原因跟上一段的多层this是一样的,就是内层的this不指向外部,而指向顶层对象

var obj = {};

var f = function () {
  return this;
};

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

上面代码中,在全局环境运行函数f时,this指向全局环境;call方法可以改变this的指向,指定this指向对象obj,然后在对象obj的作用域中运行函数f。

function add(x, y) {
  return x + y;
}

var plus5 = add.bind(null, 5);
plus5(10) // 15

上面代码中,函数add内部并没有this,使用bind方法的主要目的是绑定参数x,以后每次运行新函数plus5,就只需要提供另一个参数y就够了。而且因为add内部没有this,所以bind的第一个参数是null,不过这里如果是其他对象,也没有影响。

监听事件 addEventListener

var listener = o.m.bind(o);
element.addEventListener('click', listener);
//  ...
element.removeEventListener('click', listener);

函数中又没有包含 this

5. 回调函数 callback

调用 callIt 函数时触发回调函数

function callIt(callback) {
  callback();
}

6. call, apply, bind 绑定this的方法

  1. call 第一个参数指定this的值,后面的参数是函数调用时需要的参数 eg:x,y
  2. apply 第一个参数指定this的值, 函数调用时所需的参数,是以数组的形式传递的 eg:[x, y]
  3. bind 比call方法和apply方法更进一步的是,除了绑定this以外,还可以绑定原函数的参数。
  4. call,apply 绑定this后,函数立即执行;bind 方法返回一个函数

link: http://javascript.ruanyifeng.com/oop/this.html