JS 面向对象 原型

本文深入探讨JavaScript中的面向对象编程,包括对象的创建、this的使用规则、apply与call方法的应用,以及原型继承的概念和实现。通过实例展示了如何利用原型链进行继承,并介绍了函数式编程的基本概念和闭包的特性。此外,还提到了一些继承的实现策略,如原型冒充和复制继承。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

// 面向对象
var people = {
name:"张三",
age:20,
sex:"男",
eat:function(stuff){
console.log("张三在吃"+stuff)
}
};


people.height = 175;
delete people["age"]
people.eat("苹果")


console.log(people)


// 形式二
function HelloWorld(){
this.name = "李四",
this.print = function(){
return "js"
}
}


var hw = new HelloWorld()
console.log(hw.print())// js
console.log(hw.name) // 李四
// this的使用规则:1.在最外层外,this引用的是全局变量
//   2.函数内部根据调用方式的不同选择不同的对象


x = 5; // 全局变量
var obj = {
x:3,
doit:function(){
console.log("method is called" + this.x)
}
}
obj.doit()// 3 谁调用指向谁
var func = obj.doit;
func() // 5 因为this指的是调用这个函数的对象,这里引用了全局变量


//apply与call使用方式()
function f(){
console.log(this.x);
}
 var obj={x:4}
f.apply(obj) // 4 通过apply调用f内部,this引用了对象obj
f.call({x:5})  // 5 
console.log("ssssssssssss")
var obj={
x:3,
doit:function(){
console.log("method is called "+this.x)}
}
var obj2={x:4};
obj.doit() // 3
obj.doit.apply(obj2)// 4




function f(a,b)
{
console.log("this.x="+this.x+"a="+a+"b="+b);
}
f.apply({x:4},[1,2]) //作为第二个参数的数列中的元素都是函数f的参数
f.call({x:4},1,2) //从第二个参数起的参数都是函数f的参数




// 原型继承
// function Person(){
// // 初始化内容
// this.height=180
// }
// // 他有一个名叫prototype的属性
// Person.prototype = {
// name:"zhangsan",
// age:26,
// gender:"man",
// eat:function(food){
// console.log("I'm eatting",food)
// }
// }
// // 使用new关键字构造对象
// var p = new Person()
// console.log(p.name)
// p.eat("apple")
// console.log(p.height)




// // 相当于带两个参数的构造函数
// function People(name,age){
// this.name = name;
// this.age = age;
// this.getName = function(){
// return this.name;
// }
// }
// var a = new People("A",18)
// var b = new People("B",20)
// console.log(a.name)
// console.log(b.name)
// console.log(a.getName==b.getName)// ? 为啥不相等
// console.log(b.getName)


// 对象的隐式引用
function Person( name ) {
this.name = name;
}


var p = new Person();
console.log( p.__proto__ === Person.prototype );
// 对象的隐式引用指向了prototype属性,此处为true
console.log( Person.prototype.__proto__ ===Object.prototype );// true
// 原型本身是一个Object对象,所以它的隐式引用指向了Object构造器的prototype属性
console.log( Person.__proto__ === Function.prototype );
// 构造器Person本身是一个函数对象,此处打印true


// 继承
function People(name,age){
          this.name=name;
          this.age=age;
       }
People.prototype={
          getName:function(){
              return this.name;
          },
          getAge:function(){
              return this.age;
          }
       }
function Boy(name,age,shape)
       {
          People.call(this,name,age);// 继承父类属性
          this.shape=shape;
       }
Boy.prototype=People.prototype; // 实现继承
       Boy.prototype.getShape=function(){
          return this.shape;
       }
       var boy=new Boy("kitty",6,"fat")
       console.log(boy.getName())
       console.log(boy.getShape())




// 利用原型链实现继承
function Animal(){


}
Animal.prototype = {
name:"animal",
weight:0,
eat:function(){
console.log("可以吃")
}
}
// 声明Mammal对象构造器
function Mammal(){
this.name = "mammal";
}
// 指定Mammal对象的原型为一个Animal对象
// 实际上在此创建mammal对象与animal对象间的原型
Mammal.prototype = new Animal();
// 声明Horse对象构造器
function Horse( height, weight ) {
this.name = "horse";
this.height = height;
this.weight = weight;
}
Horse.prototype = new Mammal();


// 重写eat()方法 此方法将覆盖从Animal继承过来的eat方法
Horse.prototype.eat = function(){
console.log("Horse is eating grass")
}
// 验证原型链
var horse = new Horse( 100, 300 );
console.log( horse.__proto__ === Horse.prototype );
console.log( Horse.prototype.__proto__ === Mammal.prototype );
console.log( Mammal.prototype.__proto__ === Animal.prototype );


horse.eat()


// 函数式编程
// 两种写法
// 1 函数声明
function cout(){
console.log("cout")
}   // 函数声明提升
 cout()
// 2 函数表达式   匿名函数  
// var func = function(){
// console.log("print")
// }() // 加上小括号 立即执行
// // func()


// 匿名函数
+(function(a){
    console.log(a);
}(1234));




// +function(a){
// console.log(a)
// }(123456) // 123456




// 闭包函数的缺点:常驻内存,增大内存使用量,使用不当容易造成内存泄漏
// 特性:1、函数嵌套函数 2、函数内部可以引用外部的参数和变量 2、参数和变量不会被垃圾回收机制回收


function t(){
var num = 0;
return function(){
return ++num;
}
}
var func = t()
console.log(func());
console.log(func());
console.log(func());
console.log(func());


// 原型冒充继承
// function Cat(color){
// this.color = color
// this.climb = function(){
// console.log("on the tree")
// }
// }
// function Tiger(){
// this.extend = Cat;
// this.extend.apply(this,arguments);
// this.bark = function(){
// console.log("hahaha")
// };
// delete this.extend;
// }
// var heihu = new Tiger("yellow and black")
// console.log(heihu.color)
// console.log(heihu.extend)
// heihu.climb()


// 复制继承
Object.prototype.extend = function(obj){
for (var k in obj) {
if (obj.hasOwnProperty(k)) {
if (this[k] == undefined) {
this[k] = obj[k];
};
};
};
}
var kitty = {color:"yellow",climb:function(){console.log("on the tree")}}
var heihu = {color:"yellow and black"};


heihu.extend(kitty)
console.log(heihu)
heihu.climb()


// C 结构体内没有函数  C++下结构体可以有函数
// class,struct,union异同点?
// union 的不同之处就在于,它所有的元素共享同一内存单元,且分配给union的内存size 由类型最大的元素 size 来确定,如下的内存就为一个double 类型 size 
// 什么是内存对齐,怎么实现内存对齐  #pragma push()  #pragma push() 
// 使用伪指令#pragma pack (n),C编译器将按照n个字节对齐。
// 使用伪指令#pragma pack (),取消自定义字节对齐方式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值