TypeScript 随记

150 阅读3分钟

构造函数(Constructor)

构造函数就是类。构造函数首字母大写,这是规范。

内部使用了this变量,对构造函数使用new运算符,就能生成实例对象。

function CreateCar(color,wheel){//构造函数首字母大写
    //不需要自己创建对象了
    this.color = color;//添加属性,this指向构造函数的实例对象
    this.wheel = wheel;//添加属性/
}

//实例化
var cat1 = new CreateCar("红色","4");
var cat2 = new CreateCar("蓝色","4");
alert(cat1.color);//红色

alert(cat1.constructor == CreateCar); //true
alert(cat2.constructor == CreateCar); //true

Prototype 原型

每一个构造函数都有一个prototype属性,指向另一个对象。这个对象的所有属性和方法,都会被构造函数的实例继承。__proto__

是原型链,指向实例化的函数原型。

//showWheel都是一模一样的内容,每一次生成一个实例,都必须生成重复的内容,多占用一些内存。
function CreateCar(color,wheel){
    this.color = color;
    this.wheel = wheel;
    this.showWheel = function(){//添加一个新方法
        alert(this.wheel);
    }   
}

//还是采用同样的方法,生成实例:
var cat1 = new CreateCar("红色","4");
var cat2 = new CreateCar("蓝色","4");

alert(cat1.showWheel == cat2.showWheel); //false
//这时所有实例的showWheel属性和showName方法,其实都是同一个内存地址,指向prototype对象,因此就提高了运行效率。
function CreateCar(color,wheel){
    this.color = color;
    this.wheel = wheel;
}

//方法写原型里面
CreateCar.prototype.showWheel = function(){
    alert(this.wheel);
}
CreateCar.prototype.showName = function(){
    alert('车');
}

//生成实例。
var cat1 = new CreateCar("红色","4");
var cat2 = new CreateCar("蓝色","4");
cat1.showName();//'车'

alert(cat1.showWheel == cat2.showWheel );//true
alert(cat1.showName == cat2.showName );//true
console.log(cat1.__proto__ === CreateCar.prototype); //true

对象和函数的关系

对象是由函数构造出来的。

//Object是Function 的一个实例。
Object.constructor  == Function  //true

//函数是Function 的实例,但不是Object 的实例。
function fn(){}
fn.constructor  == Function  //true
fn.constructor  == Object    //false 

//{} 与 Object 的关系
var obj = {};
obj.constructor  === Object   //true

静态方法和静态属性

只属于类而不属于实例化对象

function foo(){
    this.show = function(){
        return this;
    }
}
foo.test = 123; //静态属性
//静态方法
foo.say = function(){
    return this;
}

foo.say();//指向 foo 方法

var fn = new foo(); //实例化的新的对象,this指向这个新的对象,不能访问类的静态方法
fn.test;//undefined
fn.say(); //Noname1.html:45 Uncaught TypeError: fn.say is not a function

对象继承

//人类
function Person(name,age){
    this.name = name;
    this.age = age;
}
Person.prototype.run = function(){
    console.log('跑路~')
};
Person.prototype.say = function(){
    console.log('说话~')
};

console.log(Person.prototype);

//男人
function Man(){
    this.sex = "男";
}

Man.prototype = Person.prototype;

Man.prototype.yyy = function(){
    console.log('嘤嘤嘤');
}
//会发现Person的prototype也改变了,因为复杂对象的赋值操作是引用而不是赋值
console.log(Person.prototype);
Man.prototype == Person.prototype;//true

for in继承

//人类
function Person(name,age){
    this.name = name;
    this.age = age;
}
Person.prototype.run = function(){
    console.log('跑路~')
};
Person.prototype.say = function(){
    console.log('说话~')
};

console.log(Person.prototype);

//男人
function Man(){
    this.sex = "男";
}

for(var key in Person.prototype){
    Man.prototype[key] = Person.prototype[key];
    console.log(key)
}
Man.prototype.yyy = function(){
    console.log('嘤嘤嘤');
}

console.log(Person.prototype);//对象run、对象say
console.log(Person.Man);//对象run、对象say、对象yyy

采用中介继承

function ClassA(name){
    this.name = name;
}
ClassA.prototype.say = function(){
    console.log(666);
}

//中继来做准备工作
function Ready(){}//
Ready.prototype = ClassA.prototype;//引用

//需要来继承ClassA
function ClassB(){}
ClassB.prototype = new Ready();//new 返回了一个新对象 __proto__指向被实例化的构造函数的prototype
ClassB.prototype.constructor = ClassB;
console.log(ClassB.prototype);

采用中介,使用call改变this指向

function ClassA(name){
    this.name = name;
}
ClassA.prototype.showName = function(){
    console.log(this.name);
}

//中继来做准备工作
function Ready(){}//
Ready.prototype = ClassA.prototype;//引用

//需要来继承ClassA
function ClassB(name){
    ClassA.call(this,name);
}
ClassB.prototype = new Ready();//new 返回了一个新对象 __proto__指向被实例化的构造函数的prototype
ClassB.prototype.constructor = ClassB;
console.log(ClassB.prototype);
var xiaoming = new ClassB('小明');
xiaoming.showName();

多态

同一个方法,面对不同的对象有不同的表现形式就叫做多态。

var obj = {
    eat : function(_type){
        if(_type == '猫'){
            console.log('猫粮')
        }else if (_type == "狗") {
            console.log('狗粮')
        }else{
            console.log("吃饭");
        }
    }
};
obj.eat("狗");

hasOwnProperty

查看该属性是否在这个对象本身上,只有在自身属性上才会返回真,在原型链上会返回假。

function ClassA(){}
ClassA.prototype.test = function(){
    console.log('test')
}

var a = new ClassA();
a.test();
console.log(a.hasOwnProperty('test')); //false

描述符(修饰符)

描述符是对一个属性的特性的描述,defineProperty设置描述符(修饰符),value设置属性值,configurable是否允许修饰符被改变 默认为false,enumerable 是否可以被枚举 默认为false,writable是否可以被 = 等号改变 默认为false。

var obj = {
    a : 1
};
var c = 666;
Object.defineProperty(obj,'c',{
    //value : 233,
    //enumerable : false,
    //writable : true,//他的值能否改变

    //设置的时候调用
    set : function(n){
        //n 就是等号的右边的值
        c = c*n;
    },

    //获取的时候调用
    get : function(){
        return c;
    },

    configurable : true,//是否可以再次修改修饰符
});

来源:www.jianshu.com/p/f9792fd