学习过程代码:
<!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>
关系图:
查找机制:
Object.defineProperty
学习过程代码: