• JavaScript面向对象和原型


    面向对象

    创建对象

    var box = new Object();						// 创建一个对象
    box.name = 'Lee';							// 创建一个属性并赋值
    box.age = 100;								// 
    box.run = function () {						// 创建一个方法		
    	return this.name + this.age+'运行中';
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    工厂模式

    function createObject(name,age){
    	var obj = new Object();
    	boj.name = name;
    	obj.age = age;
    	obj.run = function(){
    		return this.name+this.age+'运行中';
    	}
    	return obj;	// 返回对象引用
    }
    var box1 = createObject('jack',200);
    var box2 = createObject('kkk',300);
    var box3 = createObject('Lee',500);
    alert(box1 instanceof Object);
    alert(box2 instanceof Object);
    alert(box3 instanceof Object);// 都是Object没办法分清具体是哪一个对象
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    构造函数

    function Box(name,age){						//所有构造函数都是Object 
    	this.name = name;
    	this.age = age;
    	this.run = function () {
    		return this.name+this.age+'运行中';
    	};
    };
    var box1 = new Box('Leee',300);// 实例化 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    构造函数没有 new Object,但后台会自动 var obj = Object
    this 就相当于 new Object出来的对象
    构造函数不需要返回对象引用,它是后台自动返回的

    构造函数也是函数,但函数名第一个字母大写
    必须 new 构造函数名(),new Box(),而这个 Box 第一个字母也是大写的
    必须使用 new 运算符

    构造函数内部的方法或函数的问题

    function Box(name,age){
    	this.age = age;
    	this.nae = name;
    	this.run = function(){
    		return this.name+this.age+'运行中';
    	}
    }
    
    var box1 = new Box('Lee',200);
    var box2 = new Box('kkk',300);
    alert(box1.run == box2.run);// 输出 false,比较的是引用地址
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    构造函数内部的方法通过全局来实现引用一致

    function Box(name,age){
    	this.age = age;
    	this.nae = name;
    	this.run = run;
    }
    function run(){
    		return this.name+this.age+'运行中';
    	}
    var box1 = new Box('Lee',200);
    var box2 = new Box('kkk',300);
    alert(box1.run == box2.run);// 输出 true
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    原型

    创建的每个函数都有一个prototype属性,该属性是一个对象,包含可以由特定类型的所有实例共享的属性和方法

    function Box(){}// 构造函数函数体内什么都没有,如果有叫做实例属性,实例方法
    Box.prototype.name = 'Lee';// 原型属性
    Box.prototype.age = 20;
    Box.prototype.run = function(){
    	return this.name+this.age+'运行中';
    };// 原型方法
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    如果是实例方法,不同的实例化,它们的方法地址是不一样的,原型方法,方法的地址是共享的
    在原型声明中 _proto_ 是实例指向原型的指针
    constructor 构造属性,可以获取构造函数本身,作用是被原型指针定位,然后得到构造函数本身

    prototype.isPrototypeOf(对象实例)

    判断一个对象实例是否是指向了原型

    原型模式的执行流程

    1. 先查找构造函数实例里的属性或方法,如果有,立刻返回
    2. 如果实例里没有就去原型中找

    hasOwnProperty(属性名)

    如何判断这个属性是否在实例里

    function isProperty(object,property){
    	return !object.hasOwnProperty && (property in object);
    }
    
    • 1
    • 2
    • 3
    // 这种方式constructor指向Object,如果想指向实例对象可以添加 'constructor:Box'
    function Box(){}
    Box.prototype = {
    	constructor : Box,// 强制指向Box
    	name : 'Lee',
    	age : 200,
    	run : function (){
    		return this.name+this.age+'运行中';
    	}
    }
    // 这种方式constructor指向实例对象
    function Box(){}
    Box.prototype.name = 'Lee';
    Box.prototype.age = 20;
    Box.prototype.run = function(){
    	return this.name+this.age+'运行中';
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    内置引用的功能扩展

    String.prototype.addString = function(){
    	return this+',被添加了';
    }
    
    • 1
    • 2
    • 3

    缺点

    省略了构造函数的参数,初始化的信息都是一样的

    function Box(){}
    Box.prototype = {
    	name : 'Lee',
    	age : 100,
    	family : ['哥哥','姐姐','妹妹']
    	run : function (){
    		return this.name + this.age + '运行中';
    	}
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    构造函数 + 原型模式

    解决构造传参和共享问题

    function Box(name,age){
    	this.name = name;
    	this.age = age;
    	this.family = ['哥哥','姐姐','妹妹'];
    }
    Box.prototype = {
    	constructor : Box,
    	run : function (){
    		return this.name + this.age + '运行中';
    	}
    };
    var box=new Box('Lee',200);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    动态原型模式

    function Box(name,age){
    	this.name = name;
    	this.age = age;
    	if(typeof this.run != 'function'){
    		Box.prototype.run=function(){
    			return this.name + this.age + '运行中';
    		}
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    继承

    依靠原型链实现继承

    function Box(){				// 被继承的函数称作超类
    	this.name = 'Lee';
    }
    function Desk(){			// 继承的函数称作子类
    	this.age = 100;
    }
    Desk.prototype = new Box();// 超类实例化后的对象实例赋值给子类原型,形成链条
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    借用构造函数继承(对象冒充)继承

    对象冒充只能继承构造函数中的属性,不能继承原型中的属性

    function Box(name,age){
    	this.name = name;
    	this.age = age;
    }
    function Desk(name,age){
    	Box.call(this,name,age);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    对象冒充 + 原型链继承

    function Box(name,age){
    	this.name = name;
    	this.age = age;
    }
    function Desk(name,age){
    	Box.call(this,name,age);
    }
    Desk.prototype = new Box();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    原型式继承

    function obj(o){		// o表示要传递进来的一个对象					// F构造是一个临时新建的对象,用来存储传递过来的对象
    	function F(){}
    	F.prototype = o;
    	return new F();
    }
    // 缺点引用类型共享
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    寄生式继承(原型式 + 工厂模式)

    function obj(o){	
    	function F(){}
    	F.prototype = o;
    	return new F();
    }
    function create(o){
    	var f = obj(o);
    	return f;
    }
    // 解决两次调用的问题
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    寄生组合继承

    // 临时中转函数
    function obj(o){	
    	function F(){}
    	F.prototype = o;
    	return new F();
    }
    // 寄生函数
    function create(box,desk){
    	var f = obj(box.prototype);
    	f.constructor = desk;
    	desk.prototype = f;
    }
    function Box(name,age){
    	this.name = name;
    	this.age = age;
    }
    Box.prototype.run = function(){}
    function Desk(name,age){
    	Box.call(this,name,age);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
  • 相关阅读:
    不使用辅助变量的前提下实现两个变量的交换
    发明专利加急程序
    【不三不四的脑洞】记录一次 “街头搭讪” 之对旋转链表算法的感悟
    针对icon报错
    第十天-自动化办公-word操作
    99. 激光炸弹(二维前缀和)
    C语言--写一个函数返回bool值,来判断给定的字符串A和B(假设都是小写字母),是否是B中的字符都存在于A中,如果是返回true,否则返回false
    想考PMP,符合报名条件么?怎么报考?
    正则表达式
    软件测试公式之如何高质量的做BUG分析?
  • 原文地址:https://blog.csdn.net/qq_40850839/article/details/103904719