JavaScript高端程序设计(第壹版)学习笔记陆、七章

第肆章,面向对象的顺序设计

对象:

一、数据属性

?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”
    });

二、访问器属性

?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(),接收七个对象,一是要修改和增加属性的兑现,第二个对象属性与第一个对象要修改或增多的性质一一对应,援救的浏览器:IE玖+,FireFox四+,Safari伍+,Opera1二+,chrome

读取属性:Object.getOwnPropertyDescriptor(),接收五个参数,属性所在对象,要读取描述符的属性名称,支持的浏览器:IE9+,FireFox4+,Safari五+,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+,Firefox三.伍+,Safari伍+,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()方法:接收3个指标作为参数,重回全部可枚举的天性组成的字符串数组

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();接收五个参数:一是用作新对象原型的对象和(可选的)2个为新指标定义额外属性的目的

 

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

 

寄生式承接

寄生组合式承继

第九歌,函数表明式

始建格局:

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);
    }
});

闭包(难度也相当大)

闭包指有权访问另2个函数功效域中的变量的函数,闭包,也是3个函数

创办闭包的大面积方法是在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的同3个对象,所以在各样函数内部i都是拾,能够应用如下方法强制闭包重临预期效应:

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());