首页 > 代码库 > JS高级程序设计2

JS高级程序设计2

面向对象 ,基本模式、对象字面量模式、工厂模式、构造函数模式、原型模式、组合构造函数和原型模式、其他模式见电子书:动态原型模式、寄生构造函数模式(不推荐)、稳妥构造函数模式(要求安全的环境,不使用new 和 this)

技术分享
//面向对象
/* 【 数据属性】
*  configurable  true 通过 delete删除属性来修改属性
*  enumberable  true  通过 for-in 返回属性
*  writable true 修改属性值
*  value 数据值
*  es5 通过 Object.defineProperty(obj,属性名,对象{} ) 可对以上修改
*  属性名为 configurable/enumerable/writable/value
*  把 configurable 设置为 false后,就无法再设置为true 了,
*  调用 Object.defineProperty() 默认属性名都为 false
* */
var person = {}
Object.defineProperty(person,"name",{
  writable: false,  // 阻止修改属性值
  value:‘xiaoming‘
})
console.log(person.name)
person.name = ‘xxx‘;
console.log(person.name)
/* 【访问器属性】
* configurable  false
* enumerable
* get函数  默认 undefined
* set函数  默认 undefined
* 添加get set函数
* */
var book = {
  _year: 2014,  // 下划线表示只能通过对象方法访问的属性,可直接访问
  edition:1
}
Object.defineProperty(book,‘year‘,{
  get:function () {
    return this._year
  },
  set:function (val) {
    if(val> 2014){
      this._year = val
      this.edition += val - 2004
    }
  }
})
book.year = 2015;
console.log(book.edition);
console.log(book._year);
/* 同时定义多个属性用   Object.defineProperties() 复数 */
/* 通过 Object.getOwnPropertyDescriptor() 可查看 数据属性和 访问器属性各个值
*  js中任何对象,包括DOM对象和BOM对象都有 Object.getOwnPropertyDescriptor() 方法
*
* */
var desc =Object.getOwnPropertyDescriptor(book,‘_year‘)
console.log(desc.value);
console.log(desc.configurable);
var desc2 =Object.getOwnPropertyDescriptor(book,‘year‘)
console.log(desc2.value);  // undefined
console.log(desc2.configurable); // false

/* 【1.一般模式 】*/
var obj = new Object()
obj.name=‘name‘
console.log(‘name: ‘+obj.name);

/* 2.对象字面量 */
var obj2 = {
  name: ‘mama‘
}
console.log(‘mama: ‘+obj2.name);

/*【 3.工厂模式】 */
function cretePerson(name,age) {
  var o = new Object();
  o.name = name;
  o.age = age;
  o.sayName =function () {
    console.log(‘xx: ‘ + this.name);
  }
  return o;
}
var person1 = cretePerson(‘kang‘,22)
person1.sayName()
/* 【4.构造函数模式】*/
function Person(name, age) {
  this.name=name;
  this.age=age;
  this.sayName2=function () {
    console.log(this.name + ‘abccde‘)  // 等同于  this.sayName2 = new Function(‘...‘) 每次实例化都会 new Function(),这是缺陷
  }
}
var per2 = new Person(‘xiao‘,33) // Person() 当成构造函数用,有 new
per2.sayName2()
console.log(per2 instanceof Person);

// Person(‘kangddd‘,44) //  Person() 当成普通函数用,
// window.sayName2();

var per3 = new Person(‘aa‘,33)
var per4 = new Person(‘bb‘,33)  // 实例化两个对象,里面有 sayName() 方法,ECMAScript中函数也是对象,每定义一个函数,就是实例化一个对象
console.log(‘ddd333‘ + (per3 == per4));  // + 号优先级比 == 高
console.log(‘eeefff‘ + false);

/* 【5.原型模式】
* 每个函数都有 prototype(原型)属性,是一个指针,指向一个对象
* 对象实例共享 prototype 定义的属性和方法
* */
function PersonSix() {

}
PersonSix.prototype.name = ‘li‘
PersonSix.prototype.sayName3=function () {
  console.log(this.name);
}
var per10 = new PersonSix();
per10.sayName3() // 先查找 per10有没有sayName3()方法,有则返回,没有则查找 prototype是否有 sayname3()方法


/* 每创建一个函数,都有prototype */
function test() {
  return 1
}
console.log(test); // 输入函数  function test(){}
console.log(test.prototype); // 返回一个对象  每创建一个函数,都有 prototype
console.log(test.prototype.constructor);  //  返回 函数  function test(){}

function Person100() {

}
Person100.prototype.name=‘100name‘
Person100.prototype.age=‘100age‘
var p100 = new Person100()
var p101 = new Person100()
p100.name = ‘110name‘  // 实例中新增同名属性覆盖 原型中的 name
console.log(p100.name);  //  ‘110name‘
console.log(p101.name); //   ‘100name‘
delete p100.name;  // 通过  delete 可以找回 原型中的 name
console.log(p100.name); //   ‘100name‘

console.log(p100.hasOwnProperty(‘name‘));  //  判断实例是否有某属性  hasOwnProperty
console.log(‘name‘ in p100);  // name存在于实例或者原型都会返回 true
console.log(Object.keys(Person100.prototype));  // [‘name‘,‘age‘] 拿到所有原型属性的数组
console.log(Object.getOwnPropertyNames(Person100.prototype));  // [‘constructor‘,‘name‘,‘age‘] 拿到所有原型属性的数组
console.log(‘ok ? ‘ + (p100.constructor == Person100));  // 简化前 这里是 true

/* 简化原型语法*/
function Car() {

}
Car.prototype={
  constructor: Car, // 手动指定 constructor ,省略后, car.constructor 就不再指向  Car
  name:‘baoma‘,
  age:22
}
var car = new Car()
console.log(car.name);
console.log(Car.prototype.constructor);
console.log(car.constructor == Car);  // 简化后,这里返回 false

/* 在 String.prototype中可以找到 substring() 方法 */

/* 原型模式的缺陷是 如果对象中的属性是引用类型,如 数组 , 那么某个实例修改了数组,另一个实例也拿到了修改后的数据  */

function Dog() {

}
Dog.prototype={
  constructor:Dog,
  friends:[‘kang‘,‘jia‘]
}
var f1 = new Dog()
var f2 = new Dog()
f1.friends.push(‘hehe‘)
console.log(f1.friends);  // [‘kang‘,‘jia‘,‘hehe‘]
console.log(f2.friends); // [‘kang‘,‘jia‘,‘hehe‘]

/* 【组合使用构造函数械和原型原式 】*/
function Pig(name,age) {  // 属性写在构造函数中
  this.name = name;
  this.age= age;
  this.friends = [‘dd‘,‘ee‘]
}
Pig.prototype={     // 方法写在原型中
  constructor: Person,
  sayName:function () {
    console.log(this.name);
  }
}
var pig1 = new Pig(‘piga‘,11)
var pig2 = new Pig(‘pigb‘,12)
pig1.friends.push(‘ff‘)
console.log(pig1.friends);
console.log(pig2.friends);
console.log(pig1.friends === pig2.friends);  // false
console.log(pig1.sayName === pig2.sayName);  // true
View Code

 

JS高级程序设计2