原创作品,转载请注明来源,我的博客园sogeisetsu里也有这篇文章
下面是我在写博客的源代码,您可以先不要看他,先看下面的文字部分
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>js属性</title> <script> //先构造一个函数 //先搞清楚原型链 function qust() { this.name="university";//这是公有属性 this.age=12; //这是共有方法 this.run=function () { console.log("have ran"); }; let age="12";//这是私有属性 //这是私有方法 function go() { console.log("have gone"); } } //先创建一个实例对象 let shili=new qust(); //构造函数的原型对象通过prototype来调用 console.log(qust.prototype);//打印原型对象,打印结果是object //注意,这个时候还没有改变原型对象 console.log(qust.prototype.constructor);//打印原型对象的constructor /*打印结果是如下 ƒ qust() { this.name="university";//这是公有属性 this.age=12; //这是共有方法 this.run=function () { console.log("have ran"); }; … * */ console.log(qust);//打印构造函数 /*结果如下 * ƒ qust() { this.name="university";//这是公有属性 this.age=12; //这是共有方法 this.run=function () { console.log("have ran"); }; …*/ console.log(qust === qust.prototype.constructor);//true,原型对象的constructor指向构造函数 //但是,如果我们修改了qust.prototype(原型对象),qust.prototype.constructor还指向构造函数吗? qust.prototype={//prototype保存一些构造函数共有的属性,来节省内存 type:"人类", typerun:function () { console.log('人类'); } }; console.log(qust === qust.prototype.constructor);//false,不相等了。 // 注意点: 为了不破坏原有的关系, 在给prototype赋值的时候, 需要在自定义的对象中手动的添加constructor属性, 手动的指定需要指向谁 qust.prototype={//prototype保存一些构造函数共有的属性,来节省内存 constructor:qust,//不带括号 setype:"人类", typerun:function () { console.log('人类'); } }; console.log(qust === qust.prototype.constructor);//true /* 1.对象中__proto__组成的链条我们称之为原型链 2.对象在查找属性和方法的时候, 会先在当前对象查找 如果当前对象中找不到想要的, 会依次去上一级原型对象中查找 如果找到Object原型对象都没有找到, 就会报错 */ // 放个图就明白了 let shi=new qust();//由于修改了一些东西,所以新创建一个对象 console.log(shi.setype);//打印在原型对象中定义的值,结果是人类 shi.setype="新人类"; console.log(shi.setype);//新人类 console.log(shi.__proto__);/*{setype: "人类", constructor: ƒ, typerun: ƒ}*/ console.log(shi.__proto__.setype);//人类 console.log(qust.prototype.setype);//人类 console.log(shi.__proto__===qust.prototype);//true // 注意点: 在给一个对象不存在的属性设置值的时候, 不会去原型对象中查找, 如果当前对象没有就会给当前对象新增一个不存在的属性 /* 1.在JavaScript中属性和方法分类两类 1.1实例属性/实例方法 在企业开发中通过实例对象访问的属性, 我们就称之为实例属性 在企业开发中通过实例对象调用的方法, 我们就称之为实例方法 1.2静态属性/静态方法 在企业开发中通过构造函数访问的属性, 我们就称之为静态属性 在企业开发中通过构造函数调用的方法, 我们就称之为静态方法 */ //先看一下原先设置的qust /*function qust() { this.name="university";//这是公有属性 this.age=12; //这是共有方法 this.run=function () { console.log("have ran"); }; let age="12";//这是私有属性 //这是私有方法 function go() { console.log("have gone"); } } * */ //上面的属性或方法都是通过创建实例对象才能访问或调用,所以我们叫他实例属性或实例方法 qust.school="qust";//这是一个静态属性,通过构造函数来访问 console.log(qust.school);//qust //定义一个方法 qust.getschool=function () { console.log("qust is my school"); }//这是通过构造函数访问的方法,我们称其为静态方法 qust.getschool()//调用静态方法 //qust is my school //封装性 //防止混乱构造一个新函数newqust function newqust() { this.name="university";//这是公有属性 this.age=12; //以下是修改内容 let myage=19;//设置一个私有年龄,这是在函数外面无法修改的 this.setnewage=function (newage) { if(newage>=0){ myage=newage; } }; //我们还需要一个来调用年龄 this.getage=function () { return myage; }; //这是共有方法 this.run=function () { console.log("have ran"); }; let age="12";//这是私有属性,只能在该函数里访问,在外无法访问,这就为我们的封装性提供了可能 //这是私有方法 function go() { console.log("have gone"); } } //试一下调用私有属性 console.log(newqust.age);//undefined /* * 假设一个场景,让用户设置自己的年龄,年龄吗肯定大于零的,但是通过公有属性却而已随意设置*/ let newshili=new newqust(); newshili.age=-2; console.log(newshili.age);//-2,这是荒诞的 //所以需要修改 newshili.setnewage(15); console.log(newshili.getage());//15 </script> </head> <body> </body> </html>先构造一个函数
function qust() { this.name="university";//这是公有属性 this.age=12; //这是共有方法 this.run=function () { console.log("have ran"); }; let age="12";//这是私有属性 //这是私有方法 function go() { console.log("have gone"); } }先创建一个实例对象来调用构造函数中的属性
let shili=new qust();构造函数的原型对象通过prototype来调用
console.log(qust.prototype);//打印原型对象,打印结果是object注意,这个时候还没有改变原型对象
console.log(qust.prototype.constructor);//打印原型对象的constructorqust.prototype.constructor是指向构造函数qust的。 所以👇
console.log(qust === qust.prototype.constructor);//true但是,如果我们修改了qust.prototype(原型对象),qust.prototype.constructor还指向构造函数吗? 修改qust.prototype
qust.prototype={ type:"人类", typerun:function () { console.log('人类'); } }; console.log(qust === qust.prototype.constructor);//false,不相等了。那怎么办呢? 注意点: 为了不破坏原有的关系, 在给prototype赋值的时候, 需要在自定义的对象中手动的添加constructor属性, 手动的指定需要指向谁 就像这样👇
qust.prototype={//prototype保存一些构造函数共有的属性,来节省内存 constructor:qust,//👈不带括号,注意修改的就是这里 setype:"人类", typerun:function () { console.log('人类'); } }; console.log(qust === qust.prototype.constructor);//true我们之前设置了一个对象shili,还记得吗? 我们是这样设置的,👇
let shili=new qust();shili是一个实例对象 实例对象的__proto__指向构造函数的原型对象qust.prototype console.log(shili.__proto__===qust.prototype);//true 1.对象中__proto__组成的链条我们称之为原型链 2.对象在查找属性和方法的时候, 会先在当前对象查找 如果当前对象中找不到想要的, 会依次去上一级原型对象中查找 如果找到Object原型对象都没有找到, 就会报错 放个图就明白了
let shi=new qust();//由于修改了一些东西,所以新创建一个对象 console.log(shi.setype);//打印在原型对象中定义的值,结果是人类 shi.setype="新人类"; console.log(shi.setype);//新人类 console.log(shi.__proto__);/*{setype: "人类", constructor: ƒ, typerun: ƒ}*/ console.log(shi.__proto__.setype);//人类 console.log(qust.prototype.setype);//人类 console.log(shi.__proto__===qust.prototype);//true注意点: 在给一个对象不存在的属性设置值的时候, 不会去原型对象中查找, 如果当前对象没有就会给当前对象新增一个不存在的属性
1.在JavaScript中属性和方法分类两类 1.1实例属性/实例方法 在企业开发中通过实例对象访问的属性, 我们就称之为实例属性 在企业开发中通过实例对象调用的方法, 我们就称之为实例方法 1.2静态属性/静态方法 在企业开发中通过构造函数访问的属性, 我们就称之为静态属性 在企业开发中通过构造函数调用的方法, 我们就称之为静态方法
先看一下原先设置的qust
function qust() { this.name="university";//这是公有属性 this.age=12; //这是共有方法 this.run=function () { console.log("have ran"); }; let age="12";//这是私有属性 //这是私有方法 function go() { console.log("have gone"); } }👆上面的属性或方法都是通过创建实例对象才能访问或调用,所以我们叫他实例属性或实例方法 就像这样
let shi=new qust();//由于修改了一些东西,所以新创建一个对象 console.log(shi.setype);//打印在原型对象中定义的值,结果是人类先设置一个静态属性 qust.school="qust";//这是一个静态属性,通过构造函数来访问 来调用它 console.log(qust.school);//qust
//定义一个方法 qust.getschool=function () { console.log("qust is my school"); }//这是通过构造函数访问的方法,我们称其为静态方法qust.getschool()//调用静态方法返回qust is my school
防止混乱构造一个新函数newqust
function newqust() { this.name="university";//这是公有属性 this.age=12; //这是共有方法 this.run=function () { console.log("have ran"); }; let age="12";//这是私有属性,只能在该函数里访问,在外无法访问,这就为我们的封装性提供了可能 //这是私有方法 function go() { console.log("have gone"); } }试一下调用私有属性
console.log(newqust.age);//undefined,无法调用这是私有属性,只能在该函数里访问,在外无法访问,这就为我们的封装性提供了可能 假设一个场景,让用户设置自己的年龄,年龄吗肯定大于零的,但是通过公有属性却而已随意设置
let newshili=new newqust(); newshili.age=-2; console.log(newshili.age);//-2,这是荒诞的所以需要修改,newqust修改如下
function newqust() { this.name="university";//这是公有属性 this.age=12; //以下是修改内容 let myage=19;//设置一个私有年龄,这是在函数外面无法修改的 this.setnewage=function (newage) { if(newage>=0){ myage=newage; } }; //我们还需要一个来调用年龄 this.getage=function () { return myage; }; //这是共有方法 this.run=function () { console.log("have ran"); }; let age="12";//这是私有属性,只能在该函数里访问,在外无法访问,这就为我们的封装性提供了可能 //这是私有方法 function go() { console.log("have gone"); } }可以修改年龄
newshili.setnewage(15); console.log(newshili.getage());//15如果将年龄设置成负值呢?
newshili.setnewage(-5); console.log(newshili.getage());//返回19