笔记来源:拉勾教育 - 大前端就业集训营
文章内容:学习过程中的笔记、感悟、和经验
对象
变量存储比较松散,数组会受到下标的限制,对象可以存储一系列数据,并且数据是没有顺序之分的,可以给数据自定义名称
概念
js中的对象:
可以看作生活中一个具体事物的抽象,js对象是一个无序属性的集合。
属性值可以使是基本值(基本数据)、对象或者函数,对象就是一组没有顺序的值
可以把对象看作为很多个键值对(key:value)组成的,值可以使数据和函数和对象
对象的行为和特证:
- 特征:在对相中用属性表示
- 行为:用方法表示
对象字面量
把对象字面量赋值给一个变量。非常类似于数组,内部可以包含多条数据,数据之间使用逗号分割,最后一个不要加逗号
书写方法:变量 = { 内容 }
内部数据使用键值对写法:k(属性名):y(属性值)
属性值可以使任意类型数据,比如简单数据类型、函数、对象
属性和方法:
- 属性:对象的描述性特征,一般是名词,相当于定义在对象内部的变量
- 方法:对象的行为和功能,一般是动词,定义在对象中的函数
// 使用对象字面量创建对象
var a = {
// 属性
name: 'sam',
age: 19,
sex: 'male',
// 方法
sayhi: function () {
console.log('你好');
}
}
对象数据调用和更改
调用
- .调用:
对象名.属性名 - []调用:对象名['属性名']
- 对象内部调用:
this.属性名
调用方法时,需要在调用后面加()执行
// 使用对象字面量创建对象
var a = {
// 属性
name: 'sam',
age: 19,
sex: 'male',
// 方法
sayhi: function () {
console.log('你好');
},
myname: function () {
//内部调用
console.log(this.name);
}
}
// .调用
console.log(a.name);
console.log(a.age);
console.log(a.sex);
a.sayhi();
// []调用
console.log(a['name']);
console.log(a['age']);
console.log(a['sex']);
a['sayhi']();
//执行内部调用
a.myname();
更改数据
- 更改:先调用,再赋值
- 增加:
对象名.新增属性名 = 属性值 - 删除:使用delete关键字,
delete 对象名.属性名
// 使用对象字面量创建对象
var a = {
// 属性
name: 'sam',
age: 19,
sex: 'male',
// 方法
sayhi: function () {
console.log('你好');
},
myname: function () {
//内部调用
console.log(this.name);
}
}
// 更改
a.age = 20;
console.log(a.age);
// 增加
a.height = '170cm';
console.log(a.height);
// 删除
delete a.age;
console.log(a);
其他创建对象的方法
new Object()创建对象
Object()是一个构造函数,是一种特殊的函数,主要是用来在创建对象的时候初始化对象,既为对象成员变量赋初始值,必须与new一起使用才可以,其中Object首字母要大写
new执行时候做的四件事
- 在内存中建立一个新的空对象
- 让this指向这个对象
- 执行构造函数
- 返回新对象
工厂函数创建
创建多个类似的对象,可以吧new ojiect()过程封装到一个函数内,将来调用这个函数就能创建对象,这个函数就相当于一个创建对象的工厂,用来简化代码
//工厂方法封装new
function createPerson(name, age, sex) {
//创建对象
var person = new Object();
//添加对象属性和方法
person.name = name;
person.age = age;
person.sex = sex;
person.sayhi = function () {
console.log('你好,我是' + name);
}
//输出对象
return person;
}
//创建两个对象并调用函数赋值给对象
var person1 = createPerson('张三', '19', '男');
var person2 = createPerson('李四', '20', '女');
//调用对象方法
person1.sayhi(); //你好,我是张三
person2.sayhi(); //你好,我是李四
//输出两个对象
console.log(person1);
console.log(person2);
自定义构造函数
直接使用function关键词创建构造函数(注意构造函数第一个字母要大写),不需要使用new创建,也不需要返回任何值
创建新对象的时候直接使用原来的构造函数创建对象的方法即可
//创建自定义构造函数
function Person(name, age, sex) {
//使用this增加属性和方法
this.name = name;
this.age = age;
this.sex = sex;
this.sayHi = function () {
console.log('你好,我是' + name);
}
//不需要返回任何结构
}
//直接使用构造函数方法创建对象
var person1 = new Person('张三', '19', '男');
var person2 = new Person('韩梅梅', '19', '女');
//输出两个对象看一下
console.log(person1);
console.log(person2);
//调用对象的方法
person2.sayHi();
对象遍历(for-in)
for-in循环专门用来遍历对象,内部创建一个k值,k每次参与循环都会获取此次循环的属性名,从第一个开始
//创建自定义构造函数
function Person(name, age, sex) {
//使用this增加属性和方法
this.name = name;
this.age = age;
this.sex = sex;
this.sayHi = function () {
console.log('你好,我是' + name);
}
//不需要返回任何结构
}
//直接使用构造函数方法创建对象
var person1 = new Person('张三', '19', '男');
//使用对象遍历for-in遍历对象
for (k in person1) {
console.log(k + '的属性值是' + person1[k]);
}
简单类型和复杂类型
简单类型/值类型/基本类型:在存储时,变量存储的是值的本身
复杂类型/引用类型:在存储时,变量中存储的仅仅是一个引用的地址
堆和栈
js中没有堆和栈的概念,这里使用这两个概念来演示
分配区别:
堆:操作系统自动分配,存放一些变量值,数字、字符串等,由系统触发机制自动释放
栈:存储复杂类型(函数、数组、对象等),一般是由程序员分配释放,如果程序开发者不主动释放,会由垃圾回收机制回收,最新的规则中如果这个栈不再使用后会自动释放
简单类型存储效果
简单类型数据赋值给变量,那么这个变量的值就是数据本身,如果再将这个变量赋值给另一个变量,那么会直接复制一个值给另一个变量,两个变量之间没有关系,一个改变,另一个不会发生变化
//创建变量a赋值
var a = 1;
//把a赋值给b
var b = a;
//更改a的赋值
a = 2;
//输出两个变量。可以发现a发生了变化,但是b没有变化,还是a的旧值
console.log(a, b); //2,1
简单数据类型在内存中都是单独开辟出一块空间进行存储的,即使两个变量的值相同,也不会指向同一个内存位置
复杂数据类型存储效果
复杂数据类型赋值给一个变量,会先在内存中创建一个原型,赋值给变量的时候也只是把这个内存地址赋值给变量,当这个变量再赋值给其他变量,其他变量之乡的也是同一个内存中的位置,当更改其中一个变量的值,其他指向同地址的变量的值也会发生改变
//创建变量a赋值一个复杂数据
var a = [1, 2, 3];
//把a赋值给b
var b = a;
//修改这个数据的内容
a.push(1);
//输出两个变量。可以发现a和b完全相同,证明只要两个变量指向同一个复杂数据,那么当这个数据发生变化a和b都会发生变化
console.log(a, b); //[1, 2, 3, 1],[1, 2, 3, 1]
复杂数据类型存储在堆里面,当赋值的时候会给出一个地址存储在栈里面,变量直接去栈里面调用这个地址
内置对象
Js包含三种对象:自定义对象、内置对象、浏览器对象
es包含对象:自定义对象、内置对象
使用内置对象,只需要知道对象中有哪些成员,有什么功能,然后直接使用即可(参考W3C/MDN-developer.mozilla.org/zh-CN/)
//math就是一个内置对象,可以使用MDN查看具体内置的属性和方法
console.log(Math);
//使用其中一个对象试一下,random方法用于返回一个0-1之间的随机浮点数
console.log(Math.random());
//MDN中还内置了很多扩展方法,可以直接使用
//获取20-50之间的随机数
function getRandomArbitrary(min, max) {
return Math.random() * (max - min) + min;
}
console.log(getRandomArbitrary(20, 50));
Math对象
具有数学中的常数和一些函数的方法,可以直接使用不需要创建
使用的时候可以根据需要的运算方式的不同去找对应的方法和属性
| 常用属性/方法 | 功能 |
|---|---|
| Math.PI | 圆周率 |
| Math.random() | 生成随机数 |
| Math.floor() / Math.ceil() | 向上 / 下取整数 |
| Math.round() | 取整 - 四舍五入 |
| Math.abs() | 绝对值 |
| Math..max() / Math.min() | 最大值最小值 |
| Math..sin / Math..cos() | 正弦 / 余弦 |
| Math..power() / Math.sqrt() | 求指数次幂 / 求平方根 |
//使用Math对象的方法和属性
// Math.PI - 当做一个数值来使用
//求一个半径为10的圆的周长,
console.log(2 * Math.PI * 10);
//Math.random()方法 - 返回一个0-1之间的随机数
//返回两个数值间的随机整数,包括自己
function getRandomIntInclusive(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min; //含最大值,含最小值
}
console.log(getRandomIntInclusive(10, 20)); //随机整数
//Math.floor(x) - x向下取整,小于或者等于x的最大整数
//Math.ceil() - x向上取整,大于或者等于x的最小整数
//20.5向下取整和向上取整
console.log(Math.floor(20.5)); //20
console.log(Math.ceil(20.5)); //21
//Math.round(x) - x四舍五入取整
//做几个小数的四舍五入
console.log(Math.round(10.6)); //11
console.log(Math.round(10.2)); //10
console.log(Math.round(10.5)); //11
//Math.abs(x) - 返回x的绝对值(非数字内容先进行隐式转换)
console.log(Math.abs(12.5)); //12.5
console.log(Math.abs(-12.5)); //12.5
console.log(Math.abs(null)); //0
console.log(Math.abs('string')); //NAN
console.log(Math.abs()); //NAN
//Math.max(x,y,z.......) - 返回参数里面最大的数
//Math.min(x,y,z.......) - 返回参数里面最小的数
console.log(Math.max(1, 2, 3)); //3
console.log(Math.min(1, 2, 3)); //1
const num1 = [1, 2, 3];
//使用数组方式判断更加简便
console.log(Math.max(...num1)); //3
//Math.pow(基数,幂) - 求指定次的幂
//Math.sqrt() - 求平方根
console.log(Math.pow(3, 7));
console.log(Math.pow(3, 0.5)); //使用0.5实现开平方的效果
console.log(Math.pow(81, 0.25)); //使用0.25实现开4次方的效果
//Math.sqrt(x) - 实现开平方的效果 注意:如果有x是负数则会返回NAN
console.log(Math.sqrt(2));
console.log(Math.sqrt(1));
console.log(Math.sqrt(0)); //0
console.log(Math.sqrt(-1)); //nan
console.log(Math.sqrt(-0)); //-0
数组对象Array()
创建方法
- 字面量创建
- new Array()构造函数创建
// 字面量数组对象
var arr1 = [1, 2, 3];
//构造函数创建数组(空数组)
var arr2 = new Array();
//直接穿参数创建非空数组
var arr3 = new Array('zhangsan', 2, 'aaa');
//输出三个数组
console.log(arr1); //[1, 2, 3]
console.log(arr2); //
console.log(arr3); //['zhangsan', 2, 'aaa']
//判断是什么类型的数据
console.log(typeof (arr1)); //object
//instanceof判断是否是由某个构造函数创建
console.log(arr3 instanceof Array); //true
可以使用instanceof判断是否是由某个构造函数创建,只会返回布尔值
常用方法
首尾修改数据
| 常用方法 | 功能 |
|---|---|
| push() | 数组结尾添加一个或多个元素,并返回数组操作后的长度 |
| pop() | 删除数组最后一项,并返回删除项 |
| shift() | 删除数字第一项,返回删除项 |
| unshift() | 数组开头添加一个或多个元素,并返回新长度 |
| toString() | 把数组转成字符串,使用逗号分隔每一项 |
//toString方法
var a = ['zhangsan', 'lisi'];
console.log(a.toString()); //zhangsan,lisi
//push()方法 - 数组结尾添加数据,并返回新长度,参数可以任意个
console.log(a.push('wangwu')); //3
console.log(a); //["zhangsan", "lisi", "wangwu"]
//pop()方法 - 删除最后一项数据,返回删除的数据,不需要传参
console.log(a.pop()); //wangwu
console.log(a); //["zhangsan", "lisi"]
//shift()方法 - 删除第一项数据,返回删除项,不需要传参
console.log(a.shift()); //zhangsan
console.log(a); //["lisi"]
//unshift()方法 - 在数组开头添加数据,需要传参
console.log(a.unshift(1, 2, 3)); //4
console.log(a); //[1, 2, 3, "lisi"]
案例
需求:将数组的第一项移动到数组的最后一项,剩下的数据自动前移
//需求:将数组的第一项移动到数组的最后一项,剩下的数据自动前移
var arr = ['张三', '李四', '王五', '赵六', '王二麻子'];
//先删除第一项,然后把删除的项作为参数再使用push方法添加到最后一项
arr.push(arr.shift());
console.log(arr); //["李四", "王五", "赵六", "王二麻子", "张三"]
拆分和合并
concat() - 合并方法
- 将两个数组合并为一个新的数组,原数组不会发生改变,参数可以是数组、数组变量、零散值
slice(start,end) - 拆分方法
- 从当前数组中截取一个新的数组,不影响原数组,返回新数组,包含从start到end-1的所有元素
- 参数区分正负,正值代表下标,负值代表从后到前第几个位置
- 参数可以只有一个,表示从开始位置截取到结尾
//创建一个数组
var arr = ['张三', '李四', '王五'];
var arr2 = ['赵六', '王二麻子']
//合并方法,不改变原来数组的元素,而是返回一个新的数组
console.log(arr.concat(arr2)); //["张三", "李四", "王五", "赵六", "王二麻子"]
//拆分方法,不改变原数组,截取的范围是开始到结束为止-1的位置
var arr3 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
console.log(arr3.slice(2, 7)); //[3, 4, 5, 6, 7]
//负值代表从后往前数几个数字
console.log(arr3.slice(2, -2)); //[3, 4, 5, 6, 7, 8]
console.log(arr3.slice(-7, -2)); //[4, 5, 6, 7, 8]
console.log(arr3.slice(-2, -7)); //[] - 结束位置在开始位置之前,返回空数组
//尝试只有开始位置,则返回开始位置到结尾
console.log(arr3.slice(-7)); //4, 5, 6, 7, 8, 9, 10]
删除、插入、替换
splice(index,howmany,el1,el2.......) - 删除、插入和替换数组元素,直接修改原始数组,返回删除的值
参数
- index:删除元素的开始位置
- howmany:删除多少个元素,可以是0
- el1、el2:要替换的新数据
//创建一个数组
var arr = ['张三', '李四', '王五'];
//从下标为1开始,删除1个,再插入两个数据
console.log(arr.splice(1, 1, '王二麻子', '赵六'));
console.log(arr); //["张三", "王二麻子", "赵六", "王五"]
//不删除原数组内容,直接插入
//必须有>=3个参数,并且第二个必须为空
console.log(arr.splice(2, 0, 'hhh', 'aaa'));//[] 没有删除,直接为空
console.log(arr); //["张三", "王二麻子", "hhh", "aaa", "赵六", "王五"]
位置方法
indexOf() - 查找 数据在数组中第一次出现的下标
lastIndexOf - 查找一个数据最后一次在数组中出现的下标
如果没有找到的话返回-1
//创建一个数组
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 4, 5, 9];
console.log(arr.indexOf(4)); //3
console.log(arr.lastIndexOf(5)); //9
console.log(arr.lastIndexOf(100)); //-1 找不到返回-1
排序和倒序
reverse()倒序方法
将数组完全颠倒,第一项变最后一项,最后一项变第一项
直接在原数组上更改,并且会返回倒叙后的结果
//创建一个数组
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
//倒序排列数组
console.log(arr.reverse()); //[9, 8, 7, 6, 5, 4, 3, 2, 1]
console.log(arr); //[9, 8, 7, 6, 5, 4, 3, 2, 1]
sort()排序方法
- 如果没有参数,默认按照编码顺序从小到大进行排序
- 有参数参数为一个比较函数,函数接受2个参数a和b,根据a和b判断排序关系,会有三个返回值,分别代表三种排序方式
- -1 :a排在b前面
- 1 :a排在b后面
- 0 :a和b保持不变
//创建一个数组
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 44];
//排列数组,没有参数按照编码顺序进行排列
console.log(arr.sort()); //[1, 10, 2, 20, 3, 30, 4, 44, 5, 6, 7, 8, 9]
console.log(arr); //[1, 10, 2, 20, 3, 30, 4, 44, 5, 6, 7, 8, 9]
//排列数组,使用排序函数当参数
var arr2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 44];
//从小到大排列
arr2.sort(function (a, b) {
if (a < b) {
return -1;
} else if (a > b) {
return 1;
} else {
return0;
}
})
console.log(arr2)
转字符串方法join()
将数组中所有元素转换成一个字符串,并使用参数的连字符串联起来
不修改原始数组,返回字符串
//创建一个数组
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 44];
//转字符串
console.log(arr.join('-')); //1-2-3-4-5-6-7-8-9-10-20-30-44
console.log(arr); //[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 44]
清空数组的方法
- arr = [] (推荐)
- arr.length = 0
- Arr.splice(0,arr.length)
基本包装类型
一般来说基本类型数据是没有属性和方法的,基本类型的数据,在进行一些特殊操作时,会被暂时包装成一个对象,使用后再销毁
字符串对象String()
字符串调用一些方法的时候,会临时被包装成字符串对象,然后就可以使用一些字符串对象自带的属性和方法
字符串特点
不可变的,只能被替换掉,所以有大量字符串拼接的时候会有效率问题,影响加载速度
字符串对象的常用方法都不会修改字符串本身,操作完成后都会返回一个新的字符串
属性和方法
- length:类似数组,返回字符串字符个数
charAt():返回参数的下标位置的字符indexOf():返回指定字符在字符串中首次出现的位置的下标,没有返回-1- concat():连接两个或者多个字符串,参数比较灵活,可以是字符串、变量、多个字符串
split():把一个字符串分割成一个字符串数组,类似于join的反向方法,参数部分是分隔符,程序寻找参数字符,如果存在,前后分隔开,如果参数是空字符串,相当于把每个字符存为一项
//创建一个字符串
var str = 'nsaidndbk这是 ¥……*&*';
//返回字符串长度
console.log(str.length); //19
//返回第17个字符
console.log(str.charAt(17)); //&
//查找第一次出现k的位置
console.log(str.indexOf('k')); //8
//字符串拼接
console.log(str.concat('我是拼接的字符串', 'sbusdbcui')); //nsaidndbk这是 ¥……*&*我是拼接的字符串sbusdbcui
//字符串分割
console.log(str.split(' ')); //["nsaidndbk这是", "", "¥……*&*"]
console.log(str.split(
'')); //["n", "s", "a", "i", "d", "n", "d", "b", "k", "这", "是", " ", " ", "¥", "…", "…", "*", "&", "*"]
//案例 :颠倒字符串
//先把字符串转数组,再倒序数组,再转字符串
var newstr = str.split('').reverse().join('');
console.log(newstr); //*&*……¥ 是这kbdndiasn
toLowerCase():字符串转小写(英文)
toUpperCase():字符串转大写(英文)
slice(start,end):提取字符串中的某个部分,并且返回新的字符串,规则、用法和数组一样
substr(开始下标,个数):从字符串中抽取指定个数的字符,参数第一个可以为负值,代表从后往前数几个字符,不写第二个值截取到最后
substring(x,y):截取指定两个下标之间字符,参数可以颠倒,默认会比较一下大小在进行截取,不写第二个参数截取到最后
//创建一个字符串
var str = 'nsDTGBUndbk这是 ¥……*&*';
//字符转大小写转换
console.log(str.toUpperCase()); //NSDTGBUNDBK这是 ¥……*&*
console.log(str.toLowerCase()); //nsdtgbundbk这是 ¥……*&*
//截取字符串
console.log(str.slice(4, 10)); //GBUndb
console.log(str.slice(8, -2)); //dbk这是 ¥……*
console.log(str.slice(-7, -2)); // ¥……*
console.log(str.slice(-15)); //Undbk这是 ¥……*&*
//截取字符串
console.log(str.substr(12, 6)); //是 ¥……
console.log(str.substr(-12, 6)); //bk这是
console.log(str.substr(-12)); //bk这是 ¥……*&*
//截取字符串
console.log(str.substring(10, 8)); //db
console.log(str.substring(4, 19)); //GBUndbk这是 ¥……*