面向对象
面向对象概述
面向对象程序设计,英文全称Object Oriented Programming,简称OOP 在这里中文翻译成了对象,
他是将人类的思维融入到了代码中的一种编程范式,在面向对象思想提出来之前,有很长一段时
间欧式使用的面向过程的方式来编程
面向对象的特征
面向对象具备3大特征,分别是封装,继承,多态。
**封装**:把所有的编程逻辑放在一个对象中,对外提供一个方法,但外部不需要知道我
内部写了什么,代码如下:
const Computer = function (name, price) {
this.name = name;
const _price = price;
this.sayPrice = function () {
console.log(`价格为${_price}元`);
}
}
Computer.prototype.showSth = function () {
console.log(`这个${this.name}`);
}
const apple = new Computer("苹果", 6)
apple.sayPrice(); // 价格为6元
**继承**:在编程中,可以继承已存放在对象中的所有属性和方法,可以通过添加新的属
性和方法来改进其功能,代码如下:
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
sayName() {
console.log(`我叫${this.name}`);
} }
class Student extends Person {
constructor(name, age, gender, score) {
super(name, age);
this.gender = gender;
this.score = score;
}
learn() {
console.log("我是谁");
} }
const lx = new Student("二团长", 18, "男", 100);
console.log(lx.name); // 二团长
console.log(lx.age); // 18
console.log(lx.gender); // 男
console.log(lx.score); // 100
lx.sayName(); // 我叫二团长
lx.learn(); // 我是谁
**多态**:不同的对象可以分享相同的方法,还可以用一些特定的方法覆盖原来的方法,代码如下:
class Person {
constructor(name, age) {
this.name = name;
this.age = age; }
sayName() {
console.log(`我叫 ${this.name}`);
} }
class Student extends Person {
constructor(name, age, gender, score) {
super(name, age);
this.gender = gender;
this.score = score; }
sayName() {
console.log(`我的名字是${this.name}`); }
learn() {
console.log("我叫");
} }
const er= new Student("二团长", 18, "男", 100);
er.sayName(); // 我的名字是二团长
const ji= new Person("记者", 20);
ji.sayName(); // 我叫记者
描述对象
在现实生活中,我们要向别人介绍一个东西时,我们会分为2方面来进行描述,分别是
这个东西的外观和功能,而在程序中我们要描述一个对象也是2方面进行描述的
**对象功能**:描述对象具有状态,一个对象用数据值来描述它的状态。对象还有操作,
用于改变对象的状态,对象及其操作就是对象的行为
**对象特征**:被称为成员的属性,一般通过变量来存储
类
类可以看作是一个模具,对象可以看作由模具生成出来的东西,类与对象之间的关系,
可以总结为,类是对象的一种概况,而对象是类的一种具体实现要获取一个对象,首
先我们要创建一个类,下面我演示创建一个类,然后把类里面实例化出对象,代码如下:
class Computer{
constructor(name, price){
this.name=name;
this.price=price;
}
say(){
console.log(`我叫${this.name}我今年${this.price}岁`);
}
};
const i= new Computer("二团长",18);
i.say();//我叫二团长我今年18岁
this的指向
this是执行上下文中的一个属性:
activeExecutionContext = {
VO: {....},
this: thisValue
};
这里VO是我们前面讨论的变量对象。
this 与上下文中可执行代码的类型有直接关系
this 值在进入上下文时确定,并且在上下文运行期间永久不变。
全局代码中的this
在这里一切都简单。在全局代码中,this 始终是全局对象本身,这样就有可能间接的引用到它
// 显示定义全局对象的属性
this.a = 10; // global,
a = 10alert(a); // I0
//通过赋值给一个无标示符隐式
b=20;alert(this.h); // 20
// 也是通过变量声明隐试声明的
//因为全局上下文的变量对象是全局对象自身
var c=30;alert(this.c); // 30
函数代码中的this
在函数代码中使用this时很有趣,这种情况很难且会导致很多问题。
这种类型的代码中,this 值的首要特点(或许是最主要的)是它不是静态的绑定到一个函数。
正如我们上面曾提到的那样,this 是进入上下文时确定,在一一个函数代码中,这个值在每一次完全不同。
不管怎样,在代码运行时的this值是不变的,也就是说,因为它不是一个变量, 就不可能为其分配一个新值。
var foo ={
x: 10
};
var bar= {
x :20,
est: function () {
console.log(this === bar); // true
console.log(this.x); // 20
};
}
// 在进入上下文的时候
// this被当成bar对象
bar.test(); // true, 20
foo.test = bar.test; //不过,这里this依然不会是foo
//尽管调用的是相同的
functionfoo.test();//输出false, 10
那么,影响了函数代码中this值的变化有几个因素:
首先,在通常的函数调用中,this 是由激活上下文代码的调用者来提供的,即调用函数的父上下文, (parent
context)。this 取决于调用函数的方式。
为了在任何情况下准确无误的确定this值,有必要理解和记住这重要的一点。正是调用函数的方式影响了调用的上
下文中的this值。
在一些文章,甚至是在关于JavaScript的书籍中看到,它们声称: "this 值取决于函数如何定义
,如果它是全局函数,this 设置为全局对象,如果函数是一个对象的方法,this 将总是指向这个
对象。
这绝对不正确的。即使是正常的全局函数也会被调用方式的不同形式激活,这些不同的调用方
式导致了不同的this值。
function foo() {
alert(this);
}
foo(); // global
alert(foo === foo. prototype .constructor); // true
//但是同一个function的不同的调用表达式,this是不同的
foo.prototype.constructor(); // foo.prototype
// 有可能作为一些对象定义的方法来调用函数,但是this将不会设置为这个对象。
var foo= {
bar: function () {
alert(this);
alert(this === foo);
}}
foo.bar(); // foo, true
var exampleFunc = foo.bar; alert(exampleFunc === foo.bar ); //true
//再一次,同一个 function的不同的调用表达式,this是不同的
exampleFunc(); //global ,false
this的指向,是在函数被调用时决定的
1、函数以普通函数的方式被调用,这个时候this指向全局对象(浏览器:window ,Node:global)
function test(){
console.log(this)
}
test(); //全局对象
2、函数以对象的方法形式被调用,这个时候this指向当前对象
let obj = {
name:'二团长',
say:function(){
console.log(this)
}}
obj.say(); //obj
3、箭头函数的this指向,在声明的时候就已经决定 了,this和外层作用域相同
let obj = {
name:'xiejie',
say:()→{
console.log(this)
}
}
obj.say(); //全局
//指向外层作用域