Javascript面向对象

Javascript面向对象


1.理解对象

(1) 属性类型

①数据属性
1)configurable 可定义、delete、修改 默认true
2)enumerable 可for-in返回属性 默认true
3)writable 可修改值 默认true
4)value 读取该属性的时候,从这个位置读;写入该属性的时候,把新值保存在这个位置。
对象:

              var person = {
                name: "Nicholas"
              }
             Object.defineProperty(person, "name", {
                    value: "cao",
                    configurable: /*false*/true
             }); 

函数对象:

            function Person(name) {
                this.name = name;
                Object.defineProperty(this, "name", {
                    value: "cao"
                });
             }

configurable 设置为false非严格模式下delete不删除不报错,严格模式下报错。
一旦把属性定义为不可配置的,就不能再改回可配置的。再配置writable等会报错。
用Object.defineProperty()定义新属性,如果不指定,默认configurable enumerable writable默认为false。
不要在IE8中用Object.defineProperty()
②访问器属性
1)configurable 可定义、delete、修改 默认true
2)enumerable 可for-in返回属性 默认true
3)get
4)set
没有定义set则不能写,严格模式下赋值会报错。

            var book = {
                _year: 2004,
                edition: 1
             }
             Object.defineProperty(book, "year", {
                get: function() {
                    return this._year;
                },
                set: function(value) {
                    if (value > 2004) {
                        this._year = value;
                        this.edition += value - 2004;
                    }
                }
             });
             console.log(book.year);

定义访问器的旧方法:

            book.__defineGetter__("year", function() {
                return this._year;
             });
             book.__defineSetter__("year", function(value) {
                if (value > 2004) {
                        this._year = value;
                        this.edition += value - 2004;
                    }
             });
(2)定义多个属性 IE9+ 和其它…
            Object.defineProperties(book, {
                _year: {
                    writable: true,
                    value: 2004
                },
                edition: {
                    writable: true,
                    value: 1
                },
                year: {
                    get: function() {
                        return this._year;
                    },
                    set: function(value) {
                        this._year = value;
                    }
                }
             });
(3)读取属性的特性
var descriptor1 = Object.getOwnPropertyDescriptor(book, "year");
console.log(descriptor1.configurable);
console.log(typeof descriptor1.get);
console.log(typeof descriptor1.set);

2.创建对象

(1)工厂模式
(2)构造函数模式
    function Person(name, age, job) {
        this.name = name;
        this.age = age;
        this.job = job;
        this.sayName = function() {
            console.log(this.name);
        }
    }
    var o = new Object();
    Person.call(  o,  "许魏洲",  24,  "singer"  );
    o.sayName();
(3)原型模式

//Person.prototype.constructor 指向 Person
//proto属性默认存在 是实例与构造函数原型之间的连接 实例没有prototype属性
// isPrototypeOf() 判断实例原型指针是否指向指向调用者
//实例赋给属性新值 原型的同名属性被覆盖,将实例的属性delete后才能再次访问到原型的属性值
//hasOwnProperty()方法 实例属性返回true 原型属性返回false getOwnPropertyDesciptor() 原型属性

    //判断原型属性
    function hasOwnPrototypeProperty(object, name) {
        return !object.hasOwnProperty(name) && (name in object);
    }

这种方法创建的原型 constructor不指向源构造函数 指向Object构造函数,可以显示设置回去解决问题,但以这种方式设置的构造函数可枚举,原生的是不可枚举的,可通过Object.defineProperty()设置不可枚举。

function Animal() {
        if (typeOf this.sayName) {     //动态添加原型
            Animal.prototype.sayName = function() {
                console.log("name: " + this.name);
            }
        }
    }   
Animal.prototype = {
        constructor: Animal,
        name: "旺财",
        age: 0.6,
        sayName: function(){
            console.log(this.name);
        }
    }
    Object.defineProperty(Animal.prototype, "constructor", {
        enumerable: false,
        value: Animal
    });
//重写原型对象切断了原型与之前已经存在的实例之间的联系,
//实例引用的仍然是之前的原型,解决办法是动态添加原型

(4)组合使用构造函数模式和原型模式 最常用
(5)动态原型模式
(6)寄生构造函数模式 和工厂模式没有什么不同
(7)稳妥构造函数模式
和构造函数无关,不用this,实例化不用new。

3.继承

(1)原型链
每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,
而实例都包含一个指向原型对象的内部指针。
给原型添加方法的代码一定要放在替换原型的代码之后。
不能字面量方式重写原型,这样就会切断原有的链式联系。
原型链的两个问题:

1)原型中的引用类型
底层实例 和父实例 都继承了父亲的原型,都可操作父原型里面的对象
2)不能向父类型的构造函数中传参

(2)借用构造函数 没有用到链式
function SuperType(name) {
    this.name = name;
}
SuperType.prototype.sex = "男";
function SubType(name, age) {
    SuperType.call(this, name);
    this.age = age;
}
SubType.prototype.appr = "帅";
var mm = new SubType("mm", 21);
console.log(mm.name + " " + mm.age + " " + mm.sex+ " " + mm.appr);    
//  mm  21  undefined  帅

问题:1) 在超类型原型定义的方法,子类型的实例是不可见的。
2) 方法都得定义在构造函数中,函数复用无从谈起

(3)组合继承 (集前两者优点,同时解决了问题,最为常用)
        function SuperType(name) {
            this.name = name;
        }
        SuperType.prototype.sex = "男";
        function SubType(name, age) {
            SuperType.call(this, name);
            this.age = age;
        }
        SubType.prototype = new SuperType();
        //SubType.prototype.constructor = SubType;
        SubType.prototype.appr = "帅";
        var mm = new SubType("mm", 21);
        console.log(mm.name + "   " + mm.age + "   " + mm.sex + "  " + mm.appr);
(4)原型式继承 不想用构造函数实现继承
    function object(o) {
        function F(){}
        F.prototype = o;      //浅复制
        return new F();
    }

ECMAScript5实现了这一方法
Object.create()
参数1:Object.create(o)
参数2:Object.create(o, {
name: {
value: “mm”
}
})

(5)寄生式继承 由于不能做到函数复用降低了效率 如sayName
    var House = {
        name: "万达",
        address: "西安"   
    }

    function createAnother(o) {
        var clone = object(o);
        clone.sayName = function() {
            console.log("寄生继承: " + this.address
                );
        };
        return clone;
    }

    var b = createAnother(House);
    b.sayName();
(6)寄生组合式继承
    function inheritPrototype(subType, superType) {
        var prototype = object(superType.prototype);
        prototype.constructor = subType;
        subType.prototype = prototype;
    }

本质上是使用寄生式继承来继承超类型的原型
避免了在SubType.prototype上创建不必要的属性。解决了SubType.prototype = new SuperType()导致的在SubType.prototype上创建不必要的属性的问题。

4.动态添加节点

(1)createElement setAttribute 等设置属性
(2)innerHTML添加
(3)jquery版本

5. 前端对象

(1)BOM

①Window
②Document
③History
④Screen
⑤Navigtor
(2)内置对象
①Cookie
②Session
③Math
④String
⑤Date
⑥Array
⑦RegExp
⑧Number
⑨Object
⑩Function
⑪Null
⑫Boolean
⑬Error
(3)自定义对象

6. 函数对象返回对象 需new实例化得到对象

函数返回字符串 相当于返回this 不返回默认返回this
函数内部给未声明的变量赋值,需要函数执行后,该变量才会变成window全局变量

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值