ECMAScript1.4 对象 | 简单数据类型与复杂数据类型 | 内置对象 | 基本包装类型 | String
对象
函数和对象的区别:
函数:封装代码
对象:封装属性和方法
创建对象的方法:
1,对象字面量{}
// 模拟创建一只dog var dog = { // 属性 name: 'puppy', age: 3, type: '牧羊犬', color: 'yello', // 方法 bark: function () { console.log(this.name + ':汪汪'); }, eat: function () { console.log(this.name + ':在啃饲料'); } }
2,new Object()
Object是一个构造函数,首字母大写,不是普通函数。
用new的方式来调用构造函数,调用构造函数必须通过new来调用!
// 创建一个空的对象 var hero = new Object(); // 添加属性 hero.name = 'kay'; hero.age = 18; // 添加方法 hero.attck = function () { console.log(this.name + ':要打人了'); }
属于对象的函数叫方法,独立存在的叫函数。
对象字面量是这种方式的缩写,对象字面量整体的运行过程相当于以上代码一样。
new调用构造函数,会在内存中创建一个对象!
而我们调用一个普通函数是不会创建对象的!
new Object完后创建了一个对象,通过hero变量来接收这个对象。
可以随时增加属性和方法,这是javascript的动态特性。
3,工厂函数
function createHero(name, age) { // 生成一个空对象 var hero = new Object(); hero.name = name; hero.age = age; hero.attck = function () { console.log(this.name + ':打人了'); } // 返回这个对象 return hero; } // 接收这个对象 var hero = createHero('kay', 18); // 访问方法 hero.attck();
4,自定义构造函数:创建一个自己的构造函数
// 构造函数名首字母大写 function Hero(name, age) { this.name = name; this.age = age; this.run = function () { console.log(this.name + ':跑了'); } } // 生成对象 var hero1 = new Hero('kay', 18); var hero2 = new Hero('andy', 18); // 访问属性 console.log(hero1.name); // 访问方法 hero2.run();
访问属性与方法:
// 访问属性的两种方法 console.log(hero.name); console.log(hero['name']); // 访问方法 hero.attck();
new关键字的执行过程:
1,在内存中创建了一个空的对象。
2,让构造函数中的this指向刚刚创建的对象。
3,执行构造函数,在构造函数中设置属性和方法。
4,返回了当前对象
this出现在以下位置,分别代表什么:
// 1在函数中 ---- 指向window function test() { console.log(this); } test(); // window // 2 在方法中 ----- 指向这个方法所属的对象 var hero = { name: 'kay', age: 18, attck: function () { console.log(this.name + ':打人了'); } } hero.attck(); // kay:打人了 // 3 在构造函数中 ----- 指向构造函数创建的对象 function Hero(name) { this.name = name; this.attck = function () { console.log(this.name + ':打人了'); } } var hero1 = new Hero('kay'); hero1.attck(); // kay:打人了
遍历对象和删除对象的属性:
// 创建对象 var hero = { name: 'kay', age: 18, sex: 'boy' } // 遍历对象 for (var key in hero) { console.log(hero[key]); }
var hero = { name: 'kay', age: 18, sex: 'boy', attck: function () { console.log(this.name + ':跑了'); } } delete hero.name;
var params = {}; // 动态增加属性 for (var i = 1; i <= 10; i++) { params['num' + i] = i; } console.log(params);
简单数据类型与复杂数据类型:
简单数据类型(基本数据类型)如以下:
Number String Boolean Undefined Null
复杂数据类型(引用类型):
Object 数组(Array)
数据在内存中的存储:
简单数据类型存储在栈上
var n1 = 666;
var n2 = n1;
在栈上开辟一块空间,存储666(666转换成十六进制存放在这块空间)并把变量n1指向这块区域,当我们修改n1的值是不会影响n2的值的,这就是简单数据类型。
复杂数据类型存储在堆上
数组可以当做是对象
var arr1 = [12, 24, 66, 88];
var arr2 = arr1;
在堆上开辟一块空间存储arr1这个对象,并且还在栈上开辟一块空间存储这个对象堆上的内存地址,再把变量arr1指向栈上新开辟的这块空间。
接着再新开辟一块空间,然后把arr1指向堆上的内存地址复制一份赋给了arr2,此时arr1和arr2的堆上地址都是指向同一个对象,当修改arr1的数组,arr2也会跟着改变!
js没有栈和堆的概念,通过栈和堆的方式让我们容易理解代码的一些执行方式
function Params(name, age) { this.name = name; this.age = age; } // 创建对象 var p1 = new Params('kay', 18); // 都是指向同一个对象 var p2 = p1; p1.name = 'andy'; console.log(p2.name); // andy
function Person(name, age) { this.name = name; this.age = age; } var p1 = new Person('kay', 18); function fn (person) { person.name = 'jack'; } fn(p1); console.log(p1.name); // jack
// 构造函数 function Person(name, age) { this.name = name; this.age = age; } var p1 = new Person('kay', 18); function fn(person) { person.name = 'andy'; // 生成对象 person = new Person('jack', 18); console.log(person.name); // jack } fn(p1); // 访问属性 console.log(p1.name); // andy
内置对象:学习内置对象,就是学习内置对象所提供的属性和方法
javaScript的组成:ECMAScript BOM DOM
ECMAScript:有变量,数据类型,操作符,流程控制语句(判断和循环),数组,对象,构造函数,内置对象。
javascript中有三种对象:
自定义对象:这个对象的属性和方法我们自己定义。
内置对象:系统自带的,已经提供好了的对象。
浏览器对象:不属于ECMAScript
Math对象:
Math对象不是构造函数,它具有数学常数和函数的属性和方法。
都是以静态成员的方式提供跟数学相关的运算来找Math中的成员(求绝对值,取整)。
Math.PI // 圆周率 Math.random() // 生成随机数 Math.floor() // 向下取整 Math.ceil() // 向下取整 Math.round() // 四舍五入 Math.abs() // 求绝对值 Math.sin() // 正弦 Math.cos() // 余弦 Math.max() // 求最大值 Math.min() // 求最小值 Math.pow() // 求次幂 Math.sqrt() // 求平方根
job:求10到20之间的随机数
function random(min, max) { // 返回随机数 return Math.floor(Math.random() * (max - min + 1) + min); } console.log(random(10, 20));
job:随机生成颜色RGB [0到255]
// 生成随机数 function random(min, max) { return Math.floor(Math.random() * (max - min + 1) + min) ; } // 颜色拼接 function getRGB(min, max) { var color1 = random(min, max), color2 = random(min, max), color3 = random(min, max); return 'RGB:(' + color1 + ',' + color2 + ',' + color3 +')'; } console.log(getRGB(0, 255));
job:模拟实现max()和min()
// 创建对象 var myMath = { max: function () { // 假设第一个就是最大 max = arguments[0]; // 遍历这个伪数组 for (var i = 1; i < arguments.length; i++) { // 比较大小 if (max < arguments[i]) { // 重新赋值 max = arguments[i]; } } return max; }, min: function () { // 假设第一个就是最小 min = arguments[0]; // 遍历这个伪数组 for (var i = 1; i < arguments.length; i++) { // 比较大小 if (min > arguments[i]) { // 重新赋值 min = arguments[i]; } } return min; } } // 找最大值 console.log(myMath.max(12, 67, 88, 22, 99)); // 99 // 找最小值 console.log(myMath.min(12, 2, 45, 1, 78, 88)); // 1
Date对象
这是一个构造函数,要用new来创建。是实例成员
GMT:格林威治时间,世界标准
GMT + 0800 (中国标准时间):比英国快8个小时
Date构造函数的几种用法:
1,空构造函数
// 返回当前时间 var time = new Date(); console.log(time); // Mon Apr 08 2019 23:28:11 GMT+0800 (中国标准时间)
2,构造函数中传入毫秒值
// 从1970年一月一日08:00:00开始计算 var time = new Date(88888888); console.log(time); // Fri Jan 02 1970 08:41:28 GMT+0800 (中国标准时间)
3,传入日期形式的字符串
var time = new Date('2019-1-1 8:8:8'); console.log(time); // Tue Jan 01 2019 08:08:08 GMT+0800 (中国标准时间)
4,传入数字
var time = new Date(2019, 2); console.log(time); // Fri Mar 01 2019 00:00:00 GMT+0800 (中国标准时间)
获取现在离1970年的毫秒值的几种方法:
1,.valueOf()
var d = new Date(); console.log(d.valueOf()); // 1554738512959
2,.getTime()
var d = new Date(); console.log(d.getTime()); // 1554738640686
3,Date.now()
var d = Date.now(); console.log(d); // 1554738724701
4,+ new Date()
var d = + new Date(); console.log(d); // 1554738811789
Date的方法:
.toString() // 以字符串形式 .toDateString() // 只有日期 .toTimeString() // 只有时间 .toLocaleDateString() // 以本地电脑的日期格式 .toLocaleTimeString() // 以本地电脑的时间格式 获取日期的指定部分: .getMilliseconds() // 获取毫秒值 .getSeconds() // 获取秒 .getMinutes() // 获取分钟 .getHours() // 获取小时 .getDate() // 获取当月的第几天 .getDay() // 获取星期几 .getMonth() // 获取月份 这里的1月份是从0开始! .getFullYear() // 获取年份
job:格式化日期对象,返回yyyy-MM-dd HH:mm:ss的形式
// 定义函数 function formatDate(date) { // 当传入的不是Date对象 if (!(date instanceof Date)) { // 输出错误信息 console.error('date不是时间对象'); } // 年 var year = date.getFullYear(), // 月 由于一月份是从0开始的,所有要加一 month = date.getMonth() + 1, // 当月的第几日 days = date.getDate(), // 小时 hour = date.getHours(), // 分钟 minut = date.getMinutes(), // 秒 secon = date.getSeconds(); // 三元运算:当小于10,在前面加0 month = month < 10 ? '0' + month : month; days = days < 10 ? '0' + days : days; hour = hour < 10 ? '0' + hour : hour; minut = minut < 10 ? '0' + minut : minut; secon = secon < 10 ? '0' + secon : secon; // 拼接 return year + '-' + month + '-' + days + ' ' + hour + ':' + minut + ':' + secon; } // 生成对象 var d = new Date(); // 传入并打印接收的 console.log(formatDate(d)); job
job:计算时间差,返回相差的天/时/分/秒
// 定义函数 function getInterval(start, end) { // 两个日期对象相减,因为它们都是调用它们的valueOf方法进行相减 var interval = end - start; // 1秒等于1000毫秒 interval /= 1000; // 声明多个变量 var days, hour, minut, secon; // 天 days= Math.floor(interval / 60 / 60 / 24); // 小时 hour= Math.floor(interval / 60 / 60 % 24); // 分钟 minut = Math.floor(interval / 60 % 60); // 秒 secon = Math.floor(interval % 60); // 返回多个值 return { days: days, hours: hour, minutes: minut, seconds: secon } } // 当前日期 var d1 = new Date(); // 指定日期 var d2 = new Date(2019, 8, 1); // 返回一个对象 console.log(getInterval(d1, d2));
Array(数组)对象: 数组也是对象
创建数组:
1,字面量: [ ]
2,构造函数Array:new Array()
判断是不是数组:返回值(true | false)
1,instanceof
2,Array.isArray() // 有浏览器兼容性问题
清空数组:
1,arr = []
2,arr.length = 0
3,arr.splice(0, arr.length)
数组的方法:
.toString() // 转换成字符串,逗号分隔每一项 .valueOf() // 返回数组本身 // 位置:每找到返回-1,找到就返回位置 .indexOf() // 元素的位置。参数里的索引必须在前面(索引,'元素')索引可以省略 .lastIndexOf() // 从后往前找元素的位置 // 栈操作:先进后出 .push() // 追加元素 .pop() // 取走最后元素 // 队列操作:先进先出 .shift() // 取走第一个 .unshift() // 第一个元素前面插入元素 // 排序 .reverse() // 翻转数组 .sort() // 从小到大排序 // 操作 .concat() // 把参数拼接到当前数组里 .slice() // 从当前数组中截取一个新数组,不影响原数组。参数start 从0开始,end 从1开始 .splice() // 替换或删除当前数组的某项。参数start,deleteCount,options(要替换的项目)。 // 迭代方法:迭代意思就是自带遍历。html5支持 every() filter() forEach() map() some() // 将数组的所有元素连接成一个字符串 .join() // 带参数的话,就以这个参数去分割数组中的元素,返回一个字符串
sort方法:
var arr = [79, 20, 80, 45, 108]; // 括号不写参数,默认以字符编码,从小到大排序 arr.sort(); console.log(arr); // [108, 20, 45, 79, 80]
var arr = [79, 108, 23, 2, 32, 28]; arr.sort(function (a, b) { // 从小到大排 //return a - b; // 从大到小排 return b - a; }) console.log(arr); // [108, 79, 32, 28, 23, 2]
job:模拟sort方法内部实现
// 定义sort函数。(冒泡排序) function sort(arr, fn) { // 外层控制趟数,每执行完一趟就排好一个元素 for (var i = 0; i < arr.length; i++) { // 假设已排好序 var isSort = true; // 内层循环控制比较次数 for (var j = 0; j < arr.length - 1 - i; j++) { // 比较 if (fn(arr[j], arr[j + 1]) > 0) { // 还未排好序 isSort = false; // 交换位置 var tmp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = tmp; } } // 判断是否排好序 if (isSort) { // 终止循环 break; } } } var arr = [79, 108, 2, 32, 1, 45, 17]; // 传入数组和函数 sort(arr, function(a, b) { // 从小到大排 //return a - b; // 从大到小 return b - a; }); console.log(arr); // 建议使用断点形式查看代码执行过程比较容易理解!
filter迭代方法:
// 将大于2000的数放到一个新数组里。但不影响原数组 var numArr = [1200, 2800, 1500, 2000, 2200, 2500]; // filter的传入的参数是一个函数,而这个函数必须跟一个形参 var newArr = numArr.filter(function (item) { // 比较 return item > 2000; }); console.log(newArr);
job:将一个字符串数组的元素的顺序进行反转
var strArr = ['A', 'B', 'C', 'D', 'E']; // 使用reverse翻转 strArr.reverse(); console.log(strArr);
var strArr = ['A', 'B', 'C', 'D', 'E']; // 只需要遍历到一半的元素 for (var i = 0; i < Math.floor(strArr.length / 2); i++) { // 交换位置 var tmp = strArr[i]; strArr[i] = strArr[strArr.length -1 - i]; strArr[strArr.length - 1 - i] = tmp; } console.log(strArr); // ["E", "D", "C", "B", "A"]
job:找到数组中某元素出现的位置
// 找到数组中每一个o出现的位置 var arr = ['b', 'a', 'o', 'g', 'o', 'o', 'u', 'o']; // 位置 index = -1; // 先执行一遍循环体再判断条件 do { // 在index+1的位置寻找'o' index = arr.indexOf('o', index + 1); // 判断是否不等于-1 if (index !== -1) { // 打印位置 console.log(index); } } while (index !== -1);
基本包装类型
简单类型:没有属性和方法
对象:才有属性和方法
基本类型包装成复杂类型:
在javascript中有三种基本包装类型:String Number Boolean
基本类型使用方法:
系统会自动转换成基本包装类型
var s1 = 'kay jack andy'; // 基本类型调用length方法 var length = s1.length; console.log(length); // 内部执行过程 // 先创建一个临时对象 var s1 = new String('kay jack andy'); // 调用方法。调用完方法之后自动销毁 var length = s1.length; console.log(length);
var n = '888'; var num = Number(n); console.log(typeof num); // number // var obj = new Number(n); console.log(typeof obj); // Object
// 生成对象 var obj = new Boolean(false); // 之前讲过会转换为false的五种情况(是不包含Object) var result = obj && true; // console.log(result); // true
String对象
字符串的所有方法都不会修改原字符串,因为字符串的不可变性,而会返回一个新字符串!
.charAt() // 指定位置处的字符 str[] // 指定位置处的字符。html5的 .charCodeAt() // 指定位置处的ASCII字符编码 // 字符操作 .concat() // 把参数拼接到当前字符串 .slice() // 截取。起始位置,结束位置 .substring() // 截取。起始位置,结束位置 .substr() // 截取。指定位置,个数 // 位置 .indexOf() // 某字符所在位置。从前往后 .lastIndexOf() // 某字符所在位置。从后往前 // 去除空白 .trim() // 去除两边空白 // 大小写转换 .toUpperCase() // 转换为大写 .toLowerCase() // 转换为小写 // 其他 .search() // 查找字符所在位置。支持正则 .replace() // 字符替换 .split() // 切割。以字符进行,返回一个数组