面向对象
面向对象编程介绍
1. 面向对象 : 是 一种解决问题 注重结果的思维方式
面向过程 : 注重的是过程,就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候再一个一个的依次 调用就可以了。
优点:性能比面向对象高,适合跟硬件联系很紧密 的东西,例如单片机就采用的面向过程编程。
缺点:没有面向对象易维护、易复用、易扩展
面向对象(oop) : 注重的是结果,是把事务分解成为一个个对象,然后由对象之间分工与合作。
优点:易维护、易复用、易扩展,由于面向对象有封装 、继承、多态性的特性,可以设计出低耦合的系统,使 系统 更加灵活、更加易于维护
缺点:性能比面向过程低
面向对象的特性: 封装性 ,继承性 ,多态性
2. 面向对象 :本质 是对面向过程的封装
内置对象:
js作者提前封装好的对象,方便开发者直接使用
数组对象:
1. arr.concat(数组) : 把两个数组连接成一个数组
应用场景: 一般用于长列表(下一页),不断往后面拼接数组
//声明数组
let arr = [10,20,30,40,50]
arr = arr.concat([66,34,56,70])
console.log(arr)
2. arr.reverse() : 翻转数组
应用场景: 价格从低到高 切换成 从高到低, 只需要翻转数组即可
arr.reverse()
console.log(arr)
3. arr.join('分隔符') : 把数组每一个元素拼接成字符串
应用场景 : 有些歌曲是多个人合唱,服务器会给我们一个数组。 这个时候就需要将数组元素通过join拼接起来然后再页面显示
let str = arr.join('|')
console.log(str)
4. arr.sort( function(a,b){return a-b} ) : 排序
let arr1 = [12,45,67,89]
arr1.sort(function(a,b){
// return a-b // 从小到大
return b-a //从大到小
})
console.log(arr1)
字符串对象:
//声明一个数组
let str = '黑马程序员武汉大前端女神节快乐!'
1. 字符串类似于数组,也有长度和下标
console.log( str.length )//16
console.log( str[5] )//武
2. str.indexOf('字符串') 获取 ‘字符串’ 在str中的首字母下标
如果字符串存在则返回首字母下标, 如果字符串不存在则返回固定值 -1
应用场景: 一般用户判断 str中是否有某个字符串 如果没有则返回-1,不是-1说明有
let index1 = str.indexOf('大前端')
console.log( index1 )//7
let index2 = str.indexOf('大女神')
console.log( index2 )//-1
3. str.split('分隔符') 用分隔符切割字符串,得到切割之后的数组
应用场景 : 一般用户解析 网址
let url = 'http://www.baidu.com?name=张三&age=20'
console.log( url.split('|') )//['http://www.baidu.com?name=张三&age=20']
console.log( url.split('?') )//['http://www.baidu.com', 'name=张三&age=20']
console.log( url.split('=') )//['http://www.baidu.com?name', '张三&age', '20']
4. str.substr(起始下标,截取长度) 截取字符串
应用场景 : 一般后台返回的数据 不会和前端完全匹配。 有时候需要自己截取一部分
例如: 商品价格后台返回 :价格58元 但是前端只需要显示58元,就需要截取
console.log( str.substr(2,5) )//从2下标开始,往后截取5个字 程序员武汉
5.大小写转换 (中文没有大小写)
toLocaleLowerCase() 转换小写
toLocaleUpperCase()转换大写
应用场景: 字母验证码不区分大小写 (一般无论你输入什么,都会转成大写或小写保持格式统一)
console.log('dsSFJSGDJHsdfs'.toLocaleLowerCase() )//小写 dssfjsgdjhsdfs
console.log('dsSFJSGDJHsdfs'.toLocaleUpperCase() )//大写 DSSFJSGDJHSDFS
原形对象
工厂函数:用于创建对象的函数
例子:
function createPerson(name,age,sex){
// 创建对象
let p = {}
// 对象赋值
p.name = name
p.age = age
p.sex = sex
// 返回这个对象
return p
}
let p1 = createPerson('千玺',20,'男')
let p2 = createPerson('王源',20,'男')
let p3 = createPerson('王俊凯',20,'男')
console.log(p1,p2,p3)
构造函数:是使用new调用一个函数
构造函数作用与工厂函数一致,都是用来创建对象的。但是代码更加简洁。
构造函数new的工作原理:(重点面试题)
(1)创建一个对象,默认是空的
(2)this指向这个对象
(3)对象赋值
(4)返回这个对象
构造函数new在使用时需要注意的地方:(加分项)
1.构造函数首字母一般大写, 为了提醒调用者不要忘记new关键字
2.如果在构造函数内部 手动return
return 值类型 : 无效,还是返回new创建的对象
return 引用类型 : 有效,会覆盖new创建的对象
例子:
function Person(name,age,sex){
//(1)创建空对象 {}
//(2)this指向这个对象 this = {}
//(3)对象赋值
this.name = name
this.age = age
this.sex = sex
//(4)返回这个对象 return this
}
let p1 = new Person('千玺',20,'男')
console.log(p1)
原型对象(构造函数资源浪费)
(1)构造函数内部方法: 浪费内存资源
function Person(name,age){
this.name = name
this.age = age
this.eat = function(){
console.log('eat');
}
}
let p1 = new Person('张三',18)
let p2 = new Person('李四',20)
console.log( p1,p2)
/* 思考: p1和p2都有eat方法,而是函数体相同。但是他们是同一个函数吗?
不是同一个: 因为每一次调用构造函数, 内部都会执行一次function,就会在堆中开辟一个新的空间。虽然代码是一样的,但是地址不同。 就会导致每调用一次构造函数,多出一个函数堆空间。导致内存资源浪费
*/
console.log( p1.eat == p2.eat )//false
原型对象 :prototype
1.原型对象是 : 任何函数在声明的时候,系统会自动帮你创建一个对象,称之为原型对象
2.原型对象作用是 : 解决 内存浪费 + 变量污染
3.原型对象相关三个属性 ; 构造函数、原型对象、实例对象,
三者关系 (重点面试题)
prototype : 属于构造函数, 指向原型对象
__proto__ : 属于实例对象,指向原型对象 __proto__就是prototype
constructor : 属于原型对象,指向构造函数
(1)构造函数(是用new调用的函数)
function Person(name, age) {
this.name = name
this.age = age
}
(2)原型对象 prototype
console.log(Person.prototype)
Person.prototype = {
eat: function() {
console.log("吃东西")
},
learn: function() {
console.log("学习")
}
}
(3)实例对象 : 用new调用构造函数,返回的那个对象(new创建的那个对象)
let p1 = new Person('张三',20)
console.log( p1 )
let p2 = new Person('李四',22)
console.log( p1.eat == p2.eat )//true
思维图:
静态成员与实例成员
静态成员 和 实例 (属性+方法)
静态成员: 属于自己的函数成员
实例成员: 属于实例对象的成员
function Person(name,age){
this.name = name
this.age = age
}
let p1 = new Person('张三',20)
console.log( p1.name )//实例成员
console.log( p1.age )//实例成员
console.log( Person.prototype )//静态成员
console.log( Math.PI ) //静态成员 //内置对象-Math
console.log(Date.now())//静态成员 // Date.now()时间戳
//获取对象的属性值 :object.values(对象)
const arr = Object.values(p1)
console.log(arr)
1.变量作用域 :
变量 作用的范围
2. js中有三种作用域
(1)全局作用域(Script) : 页面任何地方使用
全局变量 : 大括号外面声明
(2)局部作用域(Local) : 只能在函数内部使用
局部变量: 函数内部声明的变量(形参也是局部变量)
(3)块级作用域(Block) : 在大括号(分支+循环)里面声明的变量
3.作用域链 :
* 默认情况下,js代码处在全局作用域(顶级作用域:0级),当我们声明一个函数的时候,就会开辟一个局部作用域(1级)。 如果在局部作用域中又声明函数,就会形成新的局部作用域(2级),以此类推,形成链式结构。称之为作用域链。
4.变量访问作用域链规则 : 就近原则
* 自己作用域有声明,就访问自己的。 自己没有就找上级作用域声明,如果有则访问,没有继续往上找。如果找到最顶级(0级),还是找不到。 就会报错 xxx is not defined