02-构造函数和原型
一、利用构造函数创建对象
<script>
//1.new Object()
var obj1 = new Object()
//2.对象字面量
var obj2 = {}
//3.利用构造函数
function Star(name, age) {
this.name = name
this.age = age
}
</script>
二、静态成员和实例成员
<script>
function Star(name, age) {
this.name = name
this.age = age
this.song = () => {
console.log('唱歌');
}
}
var hzp = new Star('hzp', 19)
//实例成员只能通过实例化对象来访问 实例成员就是构造函数内部通过this添加的成员
console.log(hzp.name);
//不可以通过构造函数来访问实例成员
//console.log(Star.name);
hzp.song()
//2.静态成员 在构造函数 本身 上添加的成员 sex就是静态成员
Star.sex = '男'
console.log(Star.sex);
</script>
运行结果:hzp 唱歌 男
三、构造函数原型prototype
<!-- 构造函数通过原型分配的函数是所有对象所共享的 -->
<!-- 原型是一个对象 也称prototype为原型对象
作用:共享方法
-->
<script>
function Star(name, age) {
this.name = name
this.age = age
}
Star.prototype.sing = function() {
console.log(this.name + '会唱歌');
}
var zs = new Star('张三')
var ls = new Star('李四')
zs.sing()
ls.sing()
console.log(zs.sing === ls.sing);
console.dir(Star);
console.log(zs); //对象身上系统自己添加一个 __proto__指向我们构造函数的原型对象
//__proto__对象原型和原型对象prototype是等价的
//console.log(zs.__proto__ === Star.prototype);
//很多情况下 需要手动的利用constructor这个属性指回原来的构造函数
Star.prototype = {
constructor: Star,
sing: () => {
console.log('sing');
},
movie: () => {
console.log('movie');
}
}
console.log(Star.prototype.constructor);
console.log(zs.__proto__.constructor);
//2.一般情况下 我们的公共属性定义到构造函数里面 公共的方法我们放到原型对象身上
</script>
运行结果

四、构造函数、实例和原型对象三者之间关系
<!--
Star构造函数通过Star.prototype执行Star原型对象
Star原型对象通过Star.prototype.constructor指回Star构造函数
Star构造函数 new出对象实例 对象实例 对象.__proto__.constructor(对象.__proto__也就是原型对象)指回构造函数
对象实例里有个ldh.__proto__指向原型对象
-->
三者之间关系图解:

五、原型链
<script>
function Star(name, age) {
this.name = name
this.age = age
}
Star.prototype.sing = function() {
console.log('我会唱歌');
}
var hzp = new Star('胡振鹏')
//1.只要是对象就有__proto__原型,指向原型对象
console.log(Star.prototype.__proto__ === Object.prototype);
//2.Star原型对象里面的__proto__原型指向的是Object.prototype
console.log(Object.prototype.__proto__); //为null
</script>
运行结果:true null
原型链图解:

六、原型对象中this指向
<script>
function Star(name, age) {
this.name = name
this.age = age
}
Star.prototype.sing = () => {
console.log('666');
}
var hzp = new Star();
//1.在构造函数中,里面this指向的是对象实例ldh
hzp.sing()
console.log(hzp.sing);
//2.原型对象函数里面的this指向的是实例对象
</script>
运行结果:

七、扩展内置对象方法
<script>
//原型对象的应用 扩展内置对象方法
console.log(Array.prototype);
Array.prototype.sum = function() {
var sum = 0
for (var i = 0; i < this.length; i++) {
sum += this[i]
}
//console.log(this);
return sum;
}
console.log(Array.prototype);
var arr = [2, 5, 6]
console.log(arr.sum());
</script>
运行结果:

八、call方法
<script>
function fn(x, y) {
console.log(this);
console.log(x + y);
}
var o = {
name: 'andy'
}
//1.call可以调用函数
//2.call()可以改变这个函数的this指向 此时这个函数的this指向就为o
fn.call(o, 1, 12)
</script>
运行结果:对象o 13
九、借用父构造函数继承属性
<script>
//借用父构造函数继承属性
//1.父构造函数
function Father(name, age) {
this.name = name
this.age = age
}
Father.prototype.money = function() {
console.log('money');
}
//2.子构造函数
function Son(name, age) {
Father.call(this, name, age)
}
Son.prototype = new Father();
Son.prototype.constructor = Son
Son.prototype.exam = function() {
console.log('考试');
}
var son = new Son('hzp', 19)
console.log(son);
console.log(Father.prototype);
console.log(Son.prototype.exam);
</script>
运行结果:

十、原型练习

<script>
function A() {}
function B(a) {
this.a = a;
}
function C(a) {
if (a) {
this.a = a;
}
}
A.prototype.a = 1;
B.prototype.a = 1;
C.prototype.a = 1;
console.log(new A().a); //{} 1
console.log(new B().a); // {a:undefined} undefined
console.log(new C(2).a); // {a:2} 2
</script>
运行结果:1 undefined 2
<script>
var Star = function() {}
Object.prototype.a = function() {
console.log('a');
}
Function.prototype.b = function() {
console.log('b');
}
var f = new Star();
console.log(Star.prototype);
//console.log(f.__proto__);
//console.log(f.__proto__ === Star.prototype); //true
//console.log(Object.prototype === Star.prototype.__proto__);
console.log(Object.__proto__ === Function.__proto__);
console.log(f.a, f.b, Star.a, Star.b);
//f(){
// console.log('a');
//}
//undefined
// f(){
// console.log('a');
//}
// f(){
// console.log('b');
//}
</script>
运行结果:

<script>
function User() {}
User.prototype.sayHello = function() {}
var u1 = new User();
var u2 = new User();
// u1:{} u1.__proto__ => User.prototype => Object.prototype => null
// u2:{} u1.__proto__ => User.prototype => Object.prototype => null
//console.log(u1.sayHello === u2.sayHello); // true
//console.log(User.prototype.constructor); // User(){}
//console.log(User.prototype === Function.prototype); // false
// User.__proto__ => Function.prototype
//console.log(User.__proto__ === Function.prototype); // true
// Function.__proto__ => Function.prototype
//console.log(User.__proto__ === Function.__proto__); // true
// console.log(u1.__proto__ === u2.__proto__); // true
console.log(u1.__proto__ === User.__proto__); // false
// Function.__proto__ => Function.prototype
// Object.__proto__ => Function.prototype
console.log(Function.__proto__ === Object.__proto__); // true
// Function.prototype.__proto__=> Object.prototype
// Object.prototype.__proto__ => null
console.log(Function.prototype.__proto__ === Object.prototype.__proto__); // false
console.log(Function.prototype.__proto__ === Object.prototype); // true
console.log(Object.prototype.__proto__);
</script>

浙公网安备 33010602011771号