🍒将User设为ln的原型的方法
<script>
let User = {
show(){
return this.name
}
}
console.dir(User);
let ln = {
name:'lily',
}
//将User设置为ln的原型
Object.setPrototypeOf(ln,User)
console.dir(ln);
</script>
🍑使用serPrototypeof()后ln不仅有了自己的属性name,同时还继承了User的方法和属性
🍑获取ln的原型方法使用getPrototypeof()
console.log(Object.getPrototypeOf(ln));
🍒关于为什么原型上我们改变原型值的时候,如果属性不是对象则不会被改变?
let ln = {
name:'lily',
};
ln.__proto__ = {
show(){
console.log(this.name);
}
}
ln.show();//lily
ln.__proto__ = 99;
console.log(ln.__proto__)
为什么?虽然我们改变__proto__但是因为类型不同,改变不成功
原因:原型中原型中有 get __ proto__,set __proto__并不是严格意义上的属性,他是get和set会对设置的值自动进行判断的,
如何自主改变__proto__呢?
let ln = Object.create(null);//将原型为空
ln.__proto__ = 99;
console.dir(ln);
console.log(ln.__proto__);
🌈成功改变!
🍒改变构造函数的原型并不是继承
//原型的继承,而不是改变构造函数的原型
function user(){};
user.prototype.name = function(){
console.log("user.name");
}
let ln = new user();
ln.name();//user.name
function Admin(){}
Admin.prototype = user.prototype;
Admin.prototype.role = function(){
console.log("admin.name");
};
function Member(){};
Member.prototype = user.prototype;
Member.prototype.role = function(){
console.log("member.name");
}
let member = new Member();
member.name();//user.name
member.role();//member.name
let admin = new Admin();
admin.role();//member.name
可以从上图可得知,Admin,Member都将原型引用了user的原型,可以使用uer的方法和属性,但是,这使得他们自己的方法都放在了user.prototype中,相同名称的方法就会覆盖原来的值
🍒那如何继承呢?--利用对象的__proto__完成继承
//原型的继承
function user(){};
user.prototype.name = function(){
console.log("user.name");
}
let ln = new user();
ln.name();//user.name
function Admin(){}
Admin.prototype.__proto__ = user.prototype;
Admin.prototype.role = function(){
console.log("admin.name");
};
function Member(){};
Member.prototype.__proto__ = user.prototype;
Member.prototype.role = function(){
console.log("member.name");
}
let member = new Member();
member.name();//user.name
member.role();//member.name
let admin = new Admin();
admin.role();//admin.name
🌈过程:和改变构造函数的原型方法不同,构造方法自身的方法互不影响,仍然能继承到user的方法和属性
🍒使用原型工厂封装继承
// sub 继承 sup
function extend(sub,sup){
// sub.prototype.__proto__ = sup.prototype;
//创建了一个新的对象,这个对象的原型指向sup.prototype,sub.prototype指向这个新的对象
sub.prototype = Object.create(sup.prototype);
Object.defineProperty(sub.prototype,"constructor",{
value:sub,
enumerable:false//不可以被调用
}) ;
}
function User(name,age){
this.name = name;
this.age = age;
}
User.prototype.show = function(){
console.log(this.name,this.age);
}
function Admin(...args){
User.apply(this,args);
}
extend(Admin,User);
let admin = new Admin("admin",18);
admin.show();
function Member(...args){
User.apply(this,args);
}
extend(Member,User);
let member = new Member("member",24);
member.show();
🍒使用对象工厂实现继承
function User(name,age){
this.name = name;
this.age = age;
}
User.prototype.show = function(){
console.log(this.name,this.age)
}
function admin(name,age){
const instance = Object.create(User.prototype);
User.call(instance,name,age);
instance.role = function(){
console.log("is admin");
}
return instance;
}
let ln = admin('ln',25);
ln.show();
ln.role();
function member(name,age){
const instance = Object.create(User.prototype);
User.call(instance,name,age);
return instance;
}
let lily = member('lily',21);
lily.show();
🍒多继承
//错误示范,用延长原型链的方式完成多继承会使有的方法都被继承了,冗余。
function Credit(){}
extend(Request,Credit);
Credit.prototype.total = function(){
console.log("积分统计");
}
function Request(){}
extend(User,Request);
Request.prototype.ajax = function(){
console.log("请求数据");
}
function User(name,age){
this.name = name;
this.age = age;
}
extend(Admin,User);
User.prototype.show = function(){
console.log(this.name,this.age);
}
function Admin(name,age){
User.call(this,name,age);
}
let admin = new Admin('lily',21);
admin.show();
admin.ajax();
admin.total();
如图:
// 方法变为对象
const Address = {
getaddress: function(){
console.log("地址管理");
}
}
const Credit = {
total: function(){
console.log("积分统计");
}
}
const Request = {
ajax : function(){
console.log("请求数据");
}
}
function User(name,age){
this.name = name;
this.age = age;
}
User.prototype.show = function(){
console.log(this.name,this.age);
}
function Admin(name,age){
User.call(this,name,age);
}
extend(Admin,User);
Admin.prototype = Object.assign(Admin.prototype,Credit,Request);//属性合并
let admin = new Admin('lily',21);
admin.show();
admin.ajax();
admin.total();
function Member(name,age){
User.call(this,name,age);
}
extend(Member,User)
Member.prototype = Object.assign(Member.prototype,Address,Credit);
let member = new Member("tomy",25);
member.getaddress();
member.total();