Constructor, Prototype

Learning process code:

<!DOCTYPE html>
<html lang="zh">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title>构造函数和原型</title>
</head>
<body>
	
	<script>	
	<!-- 在ES6之前没有类的概念,对象不是通过类来创建,而是通过构造函数 -->
	
	// 构造函数创建对象
	function Star(name,age){
		// 实例成员  构造函数通过this执行构造的成员  name age sing  只能通过实例化的对象访问 不能Star.name 只能ldh.name
		this.name=name;
		this.age=age;
		// this.sing=function(){   //会为方法单独开辟内存空间,造成浪费内存,所以一般是放在原型对象prototype中
		// 	console.log(this.name+"会唱歌!他已经"+this.age+"岁了!");
		// }
	}
	
	
	
	// 构造函数问题  存在浪费内存问题
	
	// 构造函数原型 prototype 实现函数共享  共享的对象放在prototype
	// 公共方法放在原型对象上,实现共享,不会再开辟空间
	// Star.prototype.dance=function(){
	// 	console.log(this.name+"会跳舞!!");
	// }
	// Star.prototype.sing=function(){
	// 	console.log(this.name+"会唱歌!!");
	// }
	// 上面简化写法,但是这个简化是替换,上面是追加方法
	
   Star.prototype= {
	   constructor:Star,   //说明指向哪个构造函数,不可以省略
	   sing:function(){
		 	console.log(this.name+"会唱歌!!");
	   },
	   dance:function(){
		   console.log(this.name+"会跳舞!!");
	   }
   }
	
	let ldh=new Star("刘德华",60);    //创建一个空对象  this再指向对象,执行构造函数的代码,添加属性和方法
	ldh.sing();
	console.log(ldh.name+'----'+ldh.age);
	
	// 静态成员  实例成员
	
	// 静态成员在构造函数本身添加的成员
	Star.sex='男';
	
	//只能通过构造函数访问
	console.log(Star.sex);  //只能通过构造函数访问
	console.log(ldh.sex);  //不可以这样访问!!
	
	// 实例成员 构造函数通过this执行构造的成员  name age sing  只能通过实例化的对象访问 不能Star.name 只能ldh.name
	console.log(Star.name);  //不可以这样访问!!
	console.log(ldh.name);  //只能通过实例化的对象访问
	
	let zxy=new Star("张学友",63);
	zxy.dance();
	ldh.dance();
	console.log("1.放在prototype原型对象上,实现原型共享,不会开辟新的内存空间地址都一样");
	console.log(zxy.dance===ldh.dance);
	console.log("2.没有放在prototype原型对象上,开辟新的内存空间 地址不一样");
	console.log(zxy.sing===ldh.sing);
	// 原型是一个对象,所有的构造函数都默认有个原型对象prototype  eg: Star 默认有prototype
		console.dir(Star);
    // 每个对象有一个属性__proto__指向构造函数的原型对象prototype  也会写成[[prototype]]遍历两层
	   console.log(ldh);
	   console.log(zxy);
	   console.log("对象有一个属性—__proto__指向构造函数的原型对象prototype ");
	   console.log(ldh.__proto__===Star.prototype);
	   // 知识点!!!
	   // 方法查找规则
	   // 1.先去看对象ldh是否有这个sing方法,有就执行
	   // 2.没有和这个方法就去___proto__(对象的原型),这个对象原型指向构造函数的原型对象
	   
	   
	   // constructor构造函数  指明构造函数   告诉我们是哪个构造函数创建的
	   console.dir(ldh.__proto__);
	   console.dir(Star.prototype);
	   // console.log(ldh.__proto__.constructor);   //指向构造函数Star
	   // console.log(Star.prototype.constructor);   //指向构造函数Star
	   
	   
	   // 通过原型对象扩展方法 比如说数组
	   console.log(Array.prototype);
	   // 追加方法,只能采取.的形式
	   Array.prototype.sum=function(){
		   let sum=0;
		   for(var i=0;i<this.length;i++){
			   sum=sum+this[i];
		   }
		   return sum;
	   }
	   var arr=[1,2,3];
	   console.log(arr.sum());
	    // call方法调用
		function fn(x,y){
			console.log("继续加油");
			console.log("call可以改变this指向")
			console.log(this);
			console.log("call可以传参")
			console.log(x+y);
		}
		var o={
			name:'lhm'
		}
		//改变this指向
		fn.call(o,1,5);
		
		//构造函数继承,利用call
		function Father(name,age){
			this.name=name;
			this.age=age;
		}
		
		Father.prototype.money=function(){
			console.log("赚大钱了!!!");
		}
		
		function Son(name,age,score){
			Father.call(this,name,age);  //此时this为调用  继承父亲构造函数属性
			this.score=score;
			
		}
		// 实现继承父类prototype共享方法start
		Son.prototype=new Father();
		Son.prototype.constructor=Son;
		// 实现继承父类prototype共享方法end
		
		console.log(Son.prototype);
		console.log(Father.prototype);
		console.log("--------")
		Son.prototype.exam=function(){
			console.log("孩子要考试!!!");
		}
		let son=new Son("刘德华",60,100);
		// console.dir(Son);
	    console.log(son.name+'---'+son.age+'------'+son.score);
		console.log("习题!!!!!!")
	  function Temp(role,weapon){
	    this.role = role;
	    this.weapon = weapon;
	    this.skill = function(){
	        console.log('你会点啥');
	    }
	 }
	 
	 let son2 = new Temp('李白','剑');
	  console.log(son2.role);
	  console.log(Temp.role); //不可以通过构造函数访问实例成员1

    console.log("对象方法Object.keys() Object.values() ");
	let oo={
		name:'lhm',
		age:18,
		sex:'女'
	}
	console.log(Object.keys(oo));
	let arr2=Object.keys(oo);
	arr2.forEach((item,index)=>{
		console.log("数组遍历")
		console.log(item);
	})
	console.log(Object.values(oo));
	//define 定义  property 属性
	console.log("对象方法Object.defineProperty  修改或者新增 新增颜色暗");
	Object.defineProperty(oo,'name',{
		value:'lll'
	})
    Object.defineProperty(oo,'score',{
      	value:666,
		writable:false  ,//不允许修改属性
		enumerable:false ,//不允许遍历,但是可以读取,如下
		configurable:false //不允许删除 不允许再次定义修改特性
    })   
	oo.score=888;
	
	// enumerable:false不允许遍历start
	console.log(oo);
	let arr3=Object.keys(oo);
	arr3.forEach((item,index)=>{
		console.log("数组遍历测试2:")
		console.log(item);
	})
	// enumerable:false不允许遍历end
	
	// configurable不允许删除start
	delete oo.score;
	console.log("configurable不允许删除")
	console.log(oo);
	// configurable不允许删除end
	</script>	
</body>
</html>

relation chart:

 Find Mechanism:

Object.defineProperty

 Learning process code:

Guess you like

Origin blog.csdn.net/enhenglhm/article/details/123891627