一 对象创建
1 使用new操作符
内置或自定义的对象类型的实例可以用new操作符创建。new操作符只运行构造函数,已存在的对象不能用new再创建一次。首先new操作符创建一个空对象;然后调用构造函数同时将新创建的对象赋值给this,构造函数执行其初始化工作。
//or var dog = {}; //or var dog = new MyDogType(); var dog = new Object(); dog.name = "Scooby"; dog.owner = {}; dog.owner.name = "Mike"; dog.bark = function () { return "Woof"; }; console.log(dog.name); // Scooby console.log(dog.owner.name); // Mike console.log(dog.bark()); // Woof
2 对象字面量创建
由对象字面量创建对象很容易,且可以创建嵌套对象。
var dog = { name: "Scooby?", owner: { name: "Mike" }, bark: function () { return" Woof"; } }; console.log(dog.name); // Scooby console.log(dog.owner.name); // Mike console.log(dog.bark()); // Woof
二 成员作用域
1 私有字段
在JavaScript中,没有内置的私有字段支持。但我们可以用封闭的构造函数来实现。定义于构造函数内的变量可以作为私有字段。任何使用私有字段的方法应该在构造函数内定义。请注意,原型方法不能在构造函数中声明和使用私有字段。私有的geter和setter方法应该在构造函数中声明。
function Customer() { // private field var risk = 0; this.getRisk = function () { return risk; }; this.setRisk = function (newRisk) { risk = newRisk; }; this.checkRisk = function () { if (risk > 1000) return" Risk Warning"; return" No Risk"; }; } Customer.prototype.addOrder = function (orderAmount) { this.setRisk(orderAmount + this.getRisk()); return this.getRisk(); }; var customer = new Customer(); console.log(customer.getRisk()); // 0 console.log(customer.addOrder(2000)); // 2000 console.log(customer.checkRisk()); // Risk Warning
2 私有方法
也称为"嵌套"或"内部函数"。私有方法定义在另一个函数内且不能从外部访问。私有方法可以在函数的任何部分声明。
function Customer(name) { var that = this; var risk = 0; this.name = name; this.type = findType(); // private method function findType() { console.log(that.name); console.log(risk); return" GOLD"; } }
或者
function Customer(name) { var that = this; var risk = 0; this.name = name; // private method var findType = function () { console.log(that.name); console.log(risk); return" GOLD"; }; this.type = findType(); } var customer = new Customer("ABC Customer"); // ABC Customer // 0 console.log(customer.type); // GOLD console.log(customer.risk); // undefined
如果一个私有内部函数返回给外部调用者,那么就可以从外部调用。
function Outer() { return new Inner(); //private inner function Inner() { this.sayHello = function () { console.log('Hello'); } } } (new Outer()).sayHello(); // Hello
3 特权方法
原型方法不能访问私有字段;原型方法都是pulbic的。我们需要一种方法来声明方法
(1)可以公共访问这些方法
(2)可以访问私有成员。
这意味着特权或受保护的访问。请看下面的代码:
function Customer(orderAmount) { // private field var cost = orderAmount / 2; this.orderAmount = orderAmount; var that = this; // privileged method this.calculateProfit = function () { return that.orderAmount - cost; }; } Customer.prototype.report = function () { console.log(this.calculateProfit()); }; var customer = new Customer(3000); customer.report(); // 1500
4 公有字段
对于公有字段,原型或实例都可以使用。原型字段和方法是通过new实例共享。原型对象也是共享的。如果一个实例改变了它的对象的字段或方法,该变化并不会影响其他实例。要改变所有实例下,我们需要改变它的原型对象。
function Customer(name, orderAmount) { // public fields this.name = name; this.orderAmount = orderAmount; } Customer.prototype.type = "NORMAL"; Customer.prototype.report = function () { console.log(this.name); console.log(this.orderAmount); console.log(this.type); console.log(this.country); }; Customer.prototype.promoteType = function () { this.type = "SILVER"; }; var customer1 = new Customer("Customer 1", 10); // public field customer1.country = "A Country"; customer1.report(); // Customer 1 // 10 // NORMAL // A Country var customer2 = new Customer("Customer 2", 20); customer2.promoteType(); console.log(customer2.type); // SILVER console.log(customer1.type); // NORMAL
5 公有方法
原型方法是公有的。任何定义在this上的方法也是公有的。
function Customer() { // public method this.shipOrder = function (shipAmount) { return shipAmount; }; } // public method Customer.prototype.addOrder = function (orderAmount) { var totalOrder = 0; for (var i = 0; i < arguments.length; i++) { totalOrder += arguments[i]; } return totalOrder; }; var customer = new Customer(); // public method customer.findType = function () { return" NORMAL"; }; console.log(customer.addOrder(25, 75)); // 100 console.log(customer.shipOrder(50)); // 50 console.log(customer.findType()); // NORMAL