ECMAScriptJavaScript高级程序设计(第三版)学习笔记6、7章

第6章,面向对象的先后设计

对象:

1、数据性

?configurable,表示是否通过delete删除属性从而又定义属性,能否修改属性之特性,或是否拿性能修改为访器属性,默认为true

‚enumerbale,表示能否通过for-in访问属性,默认true

ƒwritable,表示是否修改属性值,默认true

„value,数据存储位置,默认undefined

修改默认属性特性:Object.defineProperty(),接收三独参数:属性所在对象,属性名,描述称对象,描述符对象属性必须是:configurable、enumerable、writable、value

例:

var obj = {};
Object.defineProperty(obj,”name”,{
    writable:true,
    value:”nihao”
    });

2、访问器属性

?configurable,表示能否通过delete删除属性从而又定义属性,能否修改属性的特色,或是否拿性能修改也看器属性,默认为true

‚ enumerbale,表示是否通过for-in访问属性,默认true

ƒget,读取属性时调用,默认undefined

„set,写副属性时调用,默认undefined

改得透过Object.defineProperty()

例:

var obj = {
    _year:2004,
    edition:1
}
Object.defineProperty(book,”year”,{
    get:function(){
        return this._year;
    },
    set:function(newValue){
        if(newValue > 2004){
            this._year = newValue;
            this.edition += newValue – 2004;
        }
    }
});
book.year = 2005;
alert(book.edition);    //2

概念多独特性:Object.defineProperties(),接收两个目标,一凡是使改和添加属性的实现,第二单目标属性与第一只目标要修改或者丰富的性质一一对应,支持之浏览器:IE9+,FireFox4+,Safari5+,Opera12+,chrome

读取属性:Object.getOwnPropertyDescriptor(),接收两个参数,属性所在对象,要读取描述吻合的性质名称,支持之浏览器:IE9+,FireFox4+,Safari5+,Opera12+,chrome

创建对象:

厂子模式:

function createPerson(name,age){
    var o = new Object();
    o.name = name;
    o.age = age;
    o.sayName = function(){
        alert(this.name);
    };
    return o;
}
var person1 = createPerson(“g”,29);

构造函数模式:

function Person(name,age){
    this.name = name;
    this.age = age;
    this.sayName() = function(){
        alert(this.name);
    };
}
var person = new Person(“g”,28);

星星种模式区别:

构造函数模式遭遇未欲展示创建对象,对this直接赋值,没有回语句

构造函数名首字母必须大写,必须用new操作符创建新实例

原型模式

创造的每个函数都产生一个prototype(原型)属性,这个特性是一个指针,指向一个对象,这个目标的用途是带有可以由特定项目的享有实例共享的性质和措施,换句话就是是,prototype就是通过函数创建的靶子的原型对象,好处在可是持有实例共享相同的性能和办法。

isPrototypeOf(),个人了解就是是可以用于判断有实例的原型是否与眼前原型相同

例:

Person.prototype.isPrototypeOf(person1);        //true

 

Object.getPrototypeOf(),可以回到某个实例的原型,支持的浏览器IE9+,Firefox3.5+,Safari5+,Opera12+,chrome

注:访问对象属性名时见面进行相同赖寻,先以实例对象找,不存在则交当下目标的原型对象去寻找。

注:实例中的性质若与原型对象被之特性一样,则会遮掩原型对象的属性,与达平等长长的刚可以对的直达

hasOwnProperty()方法可以规定有属性是否来自实例,不是来实例,则赶回false,否则回true

以实例上调用delete时,只会去实例上之属于性名,并无见面删除原型的习性

例:

function Person(){
}
Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.prototype.sayName = function(){
    alert(this.name);
}
var per1 = new Person();
var per2 = new Person();
per1.name = "Greg";
alert(per1.name);   //"Greg" 来自实例
alert(per2.name);   //"Nicholas"
delete per1.name;
alert(per1.name);   //"Nicholas" 来自原型
delete per1.name;
alert(per1.name);   //"Nicholas"

流动:Object.getOwnPropertyDescriptor()方法只能用来实例属性,要拿走原型属性描述符,必须一直当原型对象及调用本方

in操作符:只有当属性在实例对象被还是以原型对象中时常,返回true

例:

alert(“name” in Person);            //true
alert(“name” in per1);            //true

又采用in和hasOwnProperty可以规定该属性是在原型中,还是实例中

Object.keys()方法:接收一个目标作为参数,返回所有可枚举的特性组成的字符串数组

Object.getOwnPropertyNames()方法:接收一个目标,返回所有属性组成的字符串数组,无论是否只是枚举

再简约的原型语法:

动用上述措施其实太麻烦了,更不时使用的凡以下方法:使用对象字面量

Person.prototype = {
    name : “Nicholas”,
    age : 29
    sayName = function(){
        alert(this.name);
    }
}

而是,此办法,相当给更写了任何prototype对象,将致constructor属性不再对Person而是因于Object,虽然instanceof还是会回正确的结果,但由此constructor已经不能够确定目标类型了。

var per = new Person();
alert(per instanceof Object);    //true
alert(per instanceof Person);    //true
alert(per constructor Object);    //true
alert(per constructor Person);    //false

若constructor真的百般重大,可以如下设置

Person.prototype = {
    constructor:Person,
    name : “Nicholas”,
    age : 29
    sayName = function(){
        alert(this.name);
    }
}

如上写法会要constructor的enumerable特性被装置也true,默认情况下原生的凡false的,在兼容ECMAScript5之浏览器可用Object.defineProperty()进行设置

Object.defineProperty(Person.prototype,”constructor”,{
    enumerable:false,
    value:Person
    });

流淌:重写原型对象,将会切断现有原型与另之前都是的靶子实例之间的联系

 

承(难度比较生,需更精心研究)

 

利用原型链来实现

 

子类型要覆盖超类的法子,应该以给原型添加方法的代码放在替换原型之后,

横流:通过原型链实现连续时,不可知利用对象字面量创建原型方法,否则会还写原型链

 

假构造函数

 

做继承

 

原型式继承,Object.creat();接收两个参数:一凡是为此作新对象原型的目标及(可选的)一个乎新对象定义额外属性的目标

 

例:Object.creat(person,{name:{value:”greg”}});

 

寄生式继承

寄生组合式继承

第7节,函数表达式

缔造方式:

1、函数声明,可以函数声明提升,就是足以把施用函数的言语放在函数声明前

function funName(arg0,arg1){
    //函数体
}

2、函数表达式,不克进行函数提升,也就算是力不从心以函数创建前下函数,在这种气象下开创的函数称为匿名函数,有时也叫拉姆达函数

var funName = function(arg0,arg1){
    //函数体
}

严格模式下无法使arguments.callee来兑现递归,可以下如下方式贯彻递归:

var factorial = (function f(num){
    if(num <= 1){
        return 1;
    }else{
        return num * f(num - 1);
    }
});

闭包(难度也不略)

闭包指有权访问另一个函数作用域中的变量的函数,闭包,也是一个函数

创立闭包的大规模方法是于一个函数内部创立另一个函数

闭包只能取得包含函数即外表函数中任何变量的最终一个价值。下例可以清楚说明问题

例:

function createFuncrions(){
    var result = new Array();
    for(var i = 0;i < 10;i++){
        result[i] = function(){
            return i;
        }
    }
    return result;
}
var re = createFuncrions();
alert(re[1](2));

每个函数返回的还以凡10,而不是一旦预期般回来对应之索引值,因为createFuncrions函数最后回来时I

10,此时每个函数都引用保存着变量i的以及一个靶,所以在每个函数内部i都是10,可以用如下方法强制闭包返回预期效果:

function createFuncrions(){
    var result = new Array();
    for(var i = 0;i < 10;i++){
        result[i] = function(num){
            return function(){
                return num;
            };
        }(i);
    }
    return result;
}
var re = createFuncrions();
alert(re[2]());

各个一个还见面回到各自的索引值

拟块级作用域

利用匿名函数可以如法炮制块级作用域:

(function(){
    alert("test");    //块级作用域,没有使用圆括号将function包起来将会出错
})();

运用闭包和个人变量的显而易见不足之处在于,会当打算域链中几近找一个层次,在一定水平及影响查找速度

函数中定义之变量可以当得水平上叫私有变量,通过函数可以如法炮制出私有变量,静态私有变量

加强模块模式:

var singleton = function(){
    //private arg and private method
    var privateVariable = 10;
    function privateFunction(){
        return false;
    }

    //create obj
    var obj = new Object();
    obj.publicProperty = true;
    obj.publicFunction = function(){
        privateVariable ++;
        return privateFunction();
    };
    return obj;
}();
alert(typeof singleton);
alert(singleton.publicProperty);
alert(singleton.publicFunction());