js基础(黑马)
js进阶(day2)
1 深入对象
1.创建对象三种方式
1. 利用对象字面量创建对象
2. 利用 new Object 创建对象
3. 利用构造函数创建对象
2.构造函数
构造函数在技术上是常规函数。
不过有两个约定:1.它们的命名以大写字母开头。2.它们只能由 "new" 操作符来执行。
function Pig(name, age, gender) {
this.name = name
this.age = age
this.gener = gender
}
// 创建佩奇对象
const Peppa = new Pig('佩奇', 6, '女')
// 创建乔治对象
const George = new Pig('乔治', 3, '男')
// 创建猪妈妈对象
const Mum = new Pig('猪妈妈', 30, '女')
// 创建猪爸爸对象
const Dad = new Pig('猪爸爸', 32, '男')
console.log(Peppa)// {name: '佩奇', age: 6, gener: '女'}
说明:
1.使用 new 关键字调用函数的行为被称为实例化实例化
2.构造函数时没有参数时可以省略 ()
3.构造函数内部无需写return,返回值即为新创建的对象
4.构造函数内部的 return 返回的值无效,所以不要写return
5.new Object() new Date() 也是实例化构造函数
实例化执行过程
说明:1.创建新对象
2.构造函数this指向新对象
3.执行构造函数代码,修改this,添加新的属性
4.返回新对象
3. 实例成员&静态成员
实例成员
通过构造函数创建的对象称为实例对象,实例对象中的属性和方法称为实例成员。
说明:1.实例对象的属性和方法即为实例成员
2.为构造函数传入参数,动态创建结构相同但值不同的对象
3.构造函数创建的实例对象彼此独立互不影响。
静态成员
说明:1.构造函数的属性和方法被称为静态成员
2.一般公共特征的属性或方法静态成员设置为静态成员
3.静态成员方法中的 this 指向构造函数本身
2. 内置构造函数
在 JavaScript 中最主要的数据类型有 6 种:
基本数据类型:字符串、数值、布尔、undefined、null
引用类型:对象
但是,我们会发现有些特殊情况:
其实字符串、数值、布尔、等基本类型也都有专门的构造函数,这些我们称为包装类型。
JS中几乎所有的数据都可以基于构造函数创建。
引用类型:Object,Array,RegExp,Date 等
包装类型String,Number,Boolean 等
1.Object
Object 是内置的构造函数,用于创建普通对象。
// 通过构造函数创建普通对象
const user = new object({name: '小明', age: 15})
推荐使用字面量方式声明对象,而不是 Object 构造函数
学习三个常用静态方法(静态方法就是只有构造函数Object可以调用的):
1.Object.keys: 获取对象中所有属性(键)
2.Object.values: 获取对象中所有属性值
3.Object.assign: 用于对象拷贝
2.Array
Array 是内置的构造函数,用于创建数组
创建数组建议使用字面量创建,不用 Array 构造函数创建
1. 数组常见实例方法-核心方法
方法 | 作用 | 说明 |
forEach | 遍历数组 | 不返回,用于不改变值,经常用于查找打印输出值 |
filter | 过滤数组 | 筛选数组元素,并生成新数组 |
map | 迭代数组 | 返回新数组,新数组里面的元素是处理之后的值,经常用于处理数据 |
reduce | 累计器 | 返回函数累计处理的结果,经常用于求和等 |
reduce
reduce 返回函数累计处理的结果,经常用于求和等
语法:
arr.reduce(function(累计值, 当前元素 [,索引号][,源数组]){}, 起始值)
累计值参数:1.如果有起始值,则以起始值为准开始累计, 累计值 = 起始值
2.如果没有起始值, 则累计值以数组的第一个数组元素作为起始值开始累计
3.后面每次遍历就会用后面的数组元素 累计到 累计值 里面 (类似求和里面的 sum )
例:
const arr = [1, 5, 8]
// 1.没有初始值
const total = arr.reduce(function (prev, current) {
return prev + current
})
console.log(total) // 14
// 2.有初始值
const total = arr.reduce(function (prev, current) {
return prev + current
}, 10)
console.log(total) // 24
// 3. 箭头函数的写法
const total = arr.reduce((prev,current) => prev + current, 10)
console.log(total) // 24
3. String
1. String 常见实例方法
实例属性length用来获取字符串的度长(重点)
实例方法split('分隔符')用来将字符串拆分成数组(重点)
实例方法substring(需要截取的第一个字符的索引[,结束的索引号])用于字符串截取(重点)
实例方法startswith(检测字符串[,检测位置索引号])检测是否以某字符开头(重点)
实例方法includes(搜索的字符串[,检测位置索引号])判断一个字符串是否包含在另一个字符串中,根据情况返回true或 false(重点)
实例方法toUppercase用于将字母转换成大写
实例方法toLowerCase用于将字母转换成小写
实例方法indexof检测是否包含某字符
实例方法endsWith检测是否以某字符结尾
实例方法replace用于替换字符串,支持正则匹配
实例方法match用于查找字符串,支持正则匹配
4.Number
Number 是内置的构造函数,用于创建数值
常用方法:toFixed() 设置保留小数位的长度
js进阶(day3)
1.编程思想
1.面向过程介绍
2.面向对象介绍
在面向对象程序开发思想中,每一个对象都是功能中心,具有明确分工。
面向对象编程具有灵活、代码可复用、容易维护和开发的优点,更适合多人合作的大型软件项目。
面向对象的特性:封装性、继承性、多态性
2 构造函数
封装是面向对象思想中比较重要的一部分,js面向对象可以通过构造函数实现的封装。
同样的将变量和函数组合到了一起并能通过 this 实现数据的共享,所不同的是借助构造函数创建出来的实例对象之间是彼此不影响的
总结:构造函数体现了面向对象的封装特性;构造函数实例创建的对象彼此独立、互不影响;前面我们学过的构造函数方法很好用,但是存在浪费内存的问题
3 原型
1.原型
构造函数通过原型分配的函数是所有对象所共享的。
JavaScript 规定,每一个构造函数都有一个 prototype 属性,指向另一个对象,所以我们也称为原型对象
这个对象可以挂载函数,对象实例化不会多次创建原型上函数,节约内存
我们可以把那些不变的方法,直接定义在 prototype 对象上,这样所有对象的实例就可以共享这些方法。
构造函数和原型对象中的 this 都指向实例化的对象
构造函数和原型对象中的this 都指向实例化的对象
2. constructor 属性
在哪里? 每个原型对象里面都有个constructor 属性(constructor 构造函数)
作用:该属性指向该原型对象的构造函数, 简单理解,就是指向我的爸爸,我是有爸爸的孩子
使用场景:如果有多个对象的方法,我们可以给原型对象采取对象形式赋值。但是这样就会覆盖构造函数原型对象原来的内容,这样修改后的原型对象 constructor 就不再指向当前构造函数了。此时,我们可以在修改后的原型对象中,添加一个 constructor 指向原来的构造函数。
function Star(name){
this.name = name
}
star. prototype = {
sing: function () { console.log('唱歌') },
dance: function () { console.log('跳舞') }
}
console.log(Star.prototype.constructor) // 指向 Object
function Star( name) {
this.name = name
}
Star.prototype = {
// 手动利用 constructor 指回 Star 构造函数
constructor: Star,
sing: function () { console.log('唱歌') },
dance: function() { console.log('跳舞') }
}
console.log(Star.prototype.constructor) // 指向 Star
3.对象原型
对象都会有一个属性 __proto__ 指向构造函数的 prototype 原型对象,之所以我们对象可以使用构造函数 prototype 原型对象的属性和方法,就是因为对象有 __proto__ 原型的存在。
注意:__proto__ 是JS非标准属性
[[prototype]]和__proto__意义相同用
来表明当前实例对象指向哪个原型对象prototype
__proto__对象原型里面也有一个 constructor属性,指向创建该实例对象的构造函数
4. 原型继承
继承是面向对象编程的另一个特征,通过继承进一步提升代码封装的程度,JavaScript 中大多是借助原型对象实现继承的特性。
例如现在有Man和Woman两个对象:
1. 封装-抽取公共部分
把男人和女人公共的部分抽取出来放到人类里面
2. 继承-让男人和女人都能继承人类的一些属性和方法
把男人女人公共的属性和方法抽取出来 People,然后赋值给Man的原型对象,可以共享这些属性和方法,注意让constructor指回Man这个构造函数
3. 问题:
如果我们给男人添加了一个吸烟的方法,发现女人自动也添加这个方法
原因:
男人和女人都同时使用了同一个对象,根据引用类型的特点,他们指向同一个对象,修改一个就会都影响
4. 解决:
构造函数
new 每次都会创建一个新的对象
5.原型链
基于原型对象的继承使得不同构造函数的原型对象关联在一起,并且这种关联的关系是一种链状的结构,我们将原型对象的链状结构关系称为原型链
原型链-查找规则:
当访问一个对象的属性(包括方法)时,首先查找这个对象自身有没有该属性。如果没有就查找它的原型(也就是__proto__指向的 prototype 原型对象),如果还没有就查找原型对象的原型(Object的原型对象)依此类推一直找到 Object 为止(null),__proto__对象原型的意义就在于为对象成员查找机制提供一个方向,或者说一条路线,可以使用 instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上