JavaScript-OO

参考资料

Object-Oriented JavaScript, 2nd. Chapter 4

结构体&对象

代码

function Hero(name, age) {
  this.name = name;
  this.age = age;
}

var hero = new Hero("Tom", 10);
console.log("Name: " + hero.name);
console.log("Age: " + hero.age);

运行结果:

Name: Tom
Age: 10

要点

  • Hero()是构造函数;构造函数既然是函数,就可以传参;
  • this: 用来定义类成员(属性);
  • new:创建对象;
  • 构造函数约定俗成是首字母大写,从而和普通的函数区分开来。

对等的object literal定义方法

下面的代码和上面的示例效果类似:

var hero = {
  name: "Tom",
  age: 10
}

console.log("Name: " + hero.name);
console.log("Age: " + hero.age);

但发现在初始化对象上不太方便。

增加对象方法

在前面代码的基础上,增加成员方法。

代码

function Hero(name, age) {
  this.name = name;
  this.age = age;

  this.debug = function() {
    return "Hero[name:" + this.name + ",age:" + this.age + "]";
  };
}

var hero = new Hero("Tom", 10);
console.log(hero.debug());

运行结果:

Hero[name:Tom,age:10]

等价的写法

var hero = {
  name: "Tom",
  age: 10,

  debug: function() {
    return "Hero[name:" + this.name + ",age:" + this.age + "]";
  }
}

console.log(hero.debug());

全局对象

window

这里只讨论WEB浏览器,其全局对象名为window。

var a = 100;
console.log("a: " + a);
console.log("a: " + window.a);
console.log("a: " + window['a']);

这里的三种访问方式都是一样的。

也就是说,在JavaScript中,所有的全局变量(函数也是变量)都是全局对象window的属性。

window & new

对前面的代码进行改写,去掉new关键字,会提示undefined。

function Hero(name, age) {
  this.name = name;
  this.age = age;
}

var hero = Hero("Tom", 10); 


console.log("Value: " + typeof hero); // Value: undefined
console.log("name: " + name); // name: Tom
console.log("name: " + window.name); // name: Tom
console.log("age: " + age); // age: 10
console.log("age: " + window.age); // age: 10

// TypeError: hero is undefined
console.log("Name: " + hero.name);

原因:没有写new的时候,就认为Hero是全局对象window的属性,从而undefined。而且Hero()函数中的this,此时指的是window全局对象。——注意到name和age属性的访问方法。

而使用new的时候,就会返回一个新的对象,此时的this指向这个新对象。

构造函数背后的故事

只给出代码,不做解释。

诡异的代码

function C() {
  this.a = 1;
  return {b:2};
}

var c = new C();
console.log(c.a); // undefined 
console.log(c.b); // 2 

伪代码

可以把构造函数理解为如下的过程:

function C() {
  //var this = {};
  this.a = 1;
  // return this;
}

var c = new C();
console.log(c.a); // 1 

对象与引用

literal object

var a = {x:1, y:2};
var b = a;

function print(a) {
  console.log("(" + a.x + "," + a.y + ")");
}

function foo(a) {
  a.x++;
  a.y++;
}

print(a); // (1,2)
print(b); // (1,2)

b.y++;
print(a); // (1,3)
print(b); // (1,3)

foo(a);
print(a); // (2,4)
print(b); // (2,4)

new object

function Point(x,y) {
  this.x = x;
  this.y = y;

  this.print = function() {
    console.log("(" + a.x + "," + a.y + ")");
  };
}


var a = new Point(1,2);
var b = a;

function foo(a) {
  a.x++;
  a.y++;
}

print(a); // (1,2)
print(b); // (1,2)

b.y++;
print(a); // (1,3)
print(b); // (1,3)

foo(a);
print(a); // (2,4)
print(b); // (2,4)

prototype

function Point(x,y) {
  this.x = x;
  this.y = y;
}

Point.prototype.print = function() {
  console.log("(" + this.x + "," + this.y + ")");
};

Point.prototype.incr = function() {
  this.x++;
  this.y++;
};

function foo() {
  var a = new Point(1,2);
  a.print(); // (1,2)
  a.incr(); 
  a.print(); // (2,3)
}

foo();

名字空间

示例一

var SomeConstants = {
  ONE : 1,
  TWO : 2,
  THREE : 3};

try {
  var a = ONE;
  console.log("a:" + a);
} catch (e) {
  //Initialize a error: ReferenceError: ONE is not defined
  console.log("Initialize a error: " + e);
}

var b = SomeConstants.ONE;
console.log("b:" + b); // b:1

示例二

var NS = NS || {};

NS.SubNS = {};

NS.SubNS = {
  // Constants
  ONE : 1,
  TWO : 2,
  THREE : 3,

  // Module variables
  value : NS.SubNS.ONE,
  ob : undefined,

  // Functions
  incr: function () {
    value++;
  },

  print: function () {
    console.log("value: " + NS.SubNS.value);
  }
};

// Class
NS.SubNS.Ctor = function (msg) {
  this.message = msg;
};

NS.SubNS.Ctor.prototype.setMsg = function (msg) {
  this.message = msg;
}

NS.SubNS.Ctor.prototype.getMsg = function () {
  return this.message;
}

NS.SubNS.Ctor.prototype.print = function () {
  console.log("Message: " + this.message);
}

function foo() {
  NS.SubNS.print(); // value: undefined
  NS.SubNS.value = 100;
  NS.SubNS.print(); // value: 100

  NS.SubNS.ob = new NS.SubNS.Ctor("msg1");
  temp = NS.SubNS.ob;
  temp.print(); // Message: msg1
  temp.setMsg("another msg");
  temp.print(); // Message: another msg
}

foo();

你可能感兴趣的:(JavaScript)