// 认识对象
// 对象(object)是“键值对”的集合,表示属性和值的映射关系
// JS中,大括号表示对象
// var xiaoming = {
// 属性名(键名,key)name: '小明',
// age: 12,
// sex:'男',
// hobbies: ['足球','编程]};
// 对象的语法
// k和v之间用冒号分隔,
// 每组k : v之间用逗号分隔,最后一个k :v对后可以不书写逗号
// var obj = {
// k: v,
// k : v,
// k: v,
// k: v
// };
// 属性是否加引号
// 如果对象的属性键名不符合JS标识符命名规范,则这个键名必须用引号包裹
// var xiaoming = {
// name: '小明',age: 12,
// sex: '男',
// hobbys: [足球','游泳','编程'],
// 'favorite-book ' :‘舒克和贝塔' // 属性名中有短横,不符合J5标识符命名规范,属性名必须用引号包裹
// };
// 属性的访问
// 可以用“点语法”访问对象中指定键的值
// xiaoming.name;//'小明'
// xiaoming.age;// 12
// xiaoming.hobbys;//['足球','游泳','编程']
// 如果属性名不符合JS标识符命名规范,则必须用方括号的写法来访问
// xiaoming[ 'favorite-book ' ];//'舒克和贝塔'
// 如果属性名以变量形式存储,则必须使用方括号形式
// var obj = {
// a: 1,
// b: 2,
// c: 3
// };
// 属性名用变量存储
// var key = 'b ';
// console.log( obj.key ) ;//undefined
// console.log(obj[key]);// 2
// 属性的创建
// 如果对象本身没有某个属性值,则用点语法赋值时,这个属性会被创建出来
// var obj = {
// a: 10};
// obj.b = 40;
// 属性的删除
// 如果要删除某个对象的属性,需要使用delete操作符
// var obj = {
// a : 1,b: 2};
// delete obj.a;
// 对象的方法
// 如果某个属性值是函数,则它也被称为对象的“方法”
// var xiaoming = {
// name: '小明',age: 12,
// sex: '男',
// hobbys: ['足球','游泳',"编程'],'favorite-book' :'舒克和贝塔',
// sayHello: function () {
// console.log('你好,我是小明,今年12岁,我是个男生'); 对象的方法
// }
// };
// 方法的调用
// 使用“点语法”可以调用对象的方法
// xiaoming.sayHello();
// 方法和函数
// 方法也是函数,只不过方法是对象的“函数属性”,它需要用对象打点调用
// 在正式学习了什么是“方法”之后,就能深入理解之前我们学习的一些函数的书写形式了,比如:
// 对象的遍历
// 和遍历数组类似,对象也可以被遍历,遍历对象需要使用for. . .in...循环
// 使用for. . .in.. .循环可以遍历对象的每个键
// 在后续的ES6相关课程中,还会学习新的对象遍历的方式
// for...in.…循环
// for (var k in obj) {
// console.log('属性’+k + '的值是'+ obj[k]);
// }
![在这里插入图片描述](https://img-blog.csdnimg.cn/b362b6b186aa41c8bf99f638eb565462.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dkYWR3YTU2NQ==,size_16,color_FFFFFF,t_70#pic_center)
// 对象是引用类型值
// 对象是引用类型值,这意味着:
// 不能用var obj2 = obj1这样的语法克隆一个对象
// 使用==或者===进行对象的比较时,比较的是它们是否为内
// 存中的同一个对象,而不是比较值是否相同
// 例子1
// var obj1 = {
// a: 1,
// b: 2,
// c: 3
// };
// var obj2 = {
// a: 1,
// b: 2,
// c: 3
// };
// console.log(obj1 == obj2); // false
// console.log(obj1 === obj2); // false
//
// console.log({} == {}); // false
// console.log({} === {}); // false
//
// 例子2
// var obj3 = {
// a: 10
// };
// var obj4 = obj3;
// obj3.a ++;
// console.log(obj4); // {a: 11}
// 对象的浅克隆
// 复习什么是浅克隆:只克隆对象的“表层”,如果对象的某些属性值又是引用类型值,则不
// 使用for. . . in.. .循环即可实现对象的浅克隆
// var obj1 = {
// a: 1,
// b: 2,
// c: [44, 55, 66]
// };
// 实现浅克隆
// var obj2 = {};
// for (var k in obj1) {
// 每遍历一个k属性,就给obj2也添加一个同名的k属性
// 值和obj1的k属性值相同
// obj2[k] = obj1[k];
// }
// 为什么叫浅克隆呢?比如c属性的值是引用类型值,那么本质上obj1和obj2的
// obj1.c.push(77);
// console.log(obj2); // obj2的c属性这个数组也会被增
// console.log(obj1.c == obj2.c); // true,true就证明了数组是同一
// 对象的深克隆
// 什么是深克隆:克隆对象的全貌,不论对象的属性值是否又是引用类型值,都能将它
// var obj1 = {
// a: 1,
// b: 2,
// c: [33, 44, {
// m: 55,
// n: 66,
// p: [77, 88]
// }]
// };
// 深克隆
// function deepClone(o) {
// 要判断o是对象还是数组
// if (Array.isArray(o)) {
// 数组
// var result = [];
// for (var i = 0; i < o.length; i++) {
// result.push(deepClone(o[i]));
// }
// } else if (typeof o == 'object') {
// 对象
// var result = {};
// for (var k in o) {
// result[k] = deepClone(o[k]);
// }
// } else {
// 基本类型值
// var result = o;
// }
// return result;
// }
//
// var obj2 = deepClone(obj1);
// console.log(obj2);
//
// console.log(obj1.c == obj2.c); // false
//
// obj1.c.push(99);
// console.log(obj2); // obj2不变的,因为没有“藕断丝连”的现象
// obj1.c[2].p.push(999);
// console.log(obj2); // obj2不变的,因为没有“藕断丝连”的现象
// 函数的上下文
// 函数中可以使用this关键字,它表示函数的上下文
// 与中文中“这”类似,函数中的this具体指代什么必须通过调用函数时的“前言后语”来判断
// 函数中的this
// var xiaoming = {
// nickname:'小明',
// age: 12,
// sayHello: function () {
// console.log('我是' + this. nickname + '我' + this.age +'岁了')
// }
// };
//
// var sayHello = xiaoming.sayHello; //=>将函数“提”出来,单独存为变量
// sayHello();直接圆括号调用这个函数,而不是对象打点调用了
// 函数的上下文由调用方式决定
//同一个函数,用不同的形式调用它,则函数的上下文不同情形1:对象打点调用函数,函数中的this指代这个打点的对象xiaoming.sayHello();
//情形2:圆括号直接调用函数,函数中的this指代window对象var sayHello = xiaoming.sayHello;
//sayHello();
// 函数的上下文由调用函数的方式决定
// 函数的上下文(this关键字)由调用函数的方式决定,function是“运行时上下文”策略
// 函数如果不调用,则不能确定函数的上下文
// 规则1
// 规则1︰对象打点调用它的方法函数,则函数的上下文是这个打点的对象
// 对象.方法()
// function fn() {
// console.log(this.a + this.b);
// }
// var obj = {
// a: 66,b: 33,
// fn: fn
// };
// obj.fn(); // 99
// 案例2
// var obj1 = {
// a: 1,b: 2,
// fn: function:() {
// console.log(this.a + this.b);
// }
// };
// var obj2 = {
// a: 3,
// b: 4,
// fn: obj1.fn
// };
// obj2.fn(); //7
// 案例3
// function outer( ) {
// var a = 11;var b = 22;return {
// a: 33,b: 44,
// fn: function () {
// console.log(this.a + this.b);
// }
//
// };
// }
// outer( ).fn(); =>77
//案例4
// function fun() {
// console.log(this.a + this.b);
// }
// var obj = {
// a: 1,b: 2,c: [{
// a: 3,b: 4,c: fun}]
// };
// var a = 5;
// obj.c[0].c(); =>7
// 规则2
// 规则2:圆括号直接调用函数,则函数的上下文是window对象
// 函数()
// var obj1 = {
// a: 1,b: 2,
// fn: function () {
// console.log(this.a + this.b);
// }
// };
// var a = 3;
// var b = 4;
// var fn = obj1.fn;
// fn();-构成函数()的形式,适用规则2 //7
// function fun() {
// return this.a + this.b;
// }
// var a = 1;var b = 2;var obj = {
// a: 3,
// b: fun(),适用规则2
// fun: fun
// };
// var result = obj.fun(); 适用规则1
// console.log( result); //6
// 规则3
// 规则3:数组(类数组对象)枚举出函数进行调用,上下文是这个数组(类数组对象)
// 数组[下标]()
// var arr = [ 'A','B', 'c ', function () {
// console.log(this[]);
// }];
// arr[3](); =>适用规则3 A
// 类数组对象
// 什么是类数组对象:所有键名为自然数序列(从0开始),且有length属性的对象
// arguments对象是最常见的类数组对象,它是函数的实参列表
// function fun() {
// arguments[3]();
// }
// fun( 'A','B','c', function ( ) i
// console.log(this[1]); // B
// });
// 规则4
// 规则4:IIFE中的函数,上下文是window对象
// (function() {
// })();
// var a = 1;var obj = {
// a: 2,
// fun: (function ( ) {
// var a = this.a;
// return function () {
// console. log(a + this.a) ;
// }
// })() =>适用规则4
// };
// obj.fun(); =>规则1 //3
// 规则5
// 规则5:定时器、延时器调用函数,上下文是window对象
// setInterval(函数,时间);
// setTimeout(函数,时间);
// var obj = {
// a:1,b: 2,
// fun: function () {
// console.log(this.a + this.b);
// }
// }
// var a = 3;
// var b = 4;
// setTimeout(function() i
// obj.fun( ); =>适用规则1 结果为3
// },2000) ;
// 规则6
// 规则6:事件处理函数的上下文是绑定事件的DOM元素
// DOM元素.onclick = function () {
// };
// <body>
// <div id="box1"></div>
// <div id="box2"></div>
// <div id="box3"></div>
//
// <>
// function setColorToRed() {
// 备份上下文
// var self = this;
// setTimeout(function() {
// self.style.backgroundColor = 'red';
// }, 2000);
// }
//
// var box1 = document.getElementById('box1');
// var box2 = document.getElementById('box2');
// var box3 = document.getElementById('box3');
//
// box1.onclick = setColorToRed;
// box2.onclick = setColorToRed;
// box3.onclick = setColorToRed;
//
// call和apply能指定函数的上下文
// function sum() i
// alert(this.chinese + this.math + this.english);
// }
// var xiaoming = {
// chinese: 80,math: 95,english: 93};
//sum.call(xiaoming);
//sum.apply( xiaoming);函数.call(上下文);函数.apply(上下文);
// call和apply的区别
// call要用逗号罗列参数
// apply要把参数写到数组中
// 上下文规则总结
// 规则 上下文
// 对象.函数() 对象
// 函数() window
// 数组[下标]() 数组
// IIFE window
// 定时器 window
// DOM事件处理函数 绑定DOM的元素
// call和apply 任意指定
// 用new操作符调用函数
// 现在,我们学习一种新的函数调用方式:
// new函数()
// 你可能知道new操作符和“面向对象”息息相关,但是现在
// ,我们先不探讨它的“面向对象”意义,而是先把用new调
// 用函数的执行步骤和它上下文弄清楚
// 用new操作符调用函数
// JS规定,使用new操作符调用函数会进行“四步走”
// 1)函数体内会自动创建出一个空白对象
//
// 2)函数的上下文(this)会指向这个对象
// 3)函数体内的语句会执行
// 4)函数会自动返回上下文对象,即使函数没有return语句
![在这里插入图片描述](https://img-blog.csdnimg.cn/6034b6cd116a467098f9d07a59b9cd55.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dkYWR3YTU2NQ==,size_16,color_FFFFFF,t_70#pic_center)
![在这里插入图片描述](https://img-blog.csdnimg.cn/1acae882e6bd4655ad4955a1409509d6.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dkYWR3YTU2NQ==,size_16,color_FFFFFF,t_70#pic_center)
//什么是构造函数
//用new调用一个函数,这个函数就被称为“构造函数”,任何函数都可以是构造函数,只需要用new调用它
//顾名思义,构造函数用来“构造新对象”,它内部的语句将为新对象添加若干属性和方法,完成对象的初始化
//构造函数必须用new关键字调用,否则不能正常工作,正因如此,开发者约定构造函数命名时首字母要大写
//构造函数中的this不是函数本身
//什么是prototype
// 任何函数都有prototype属性,prototype是英语“原型”的意思
// prototype属性值是个对象,它默认拥有constructor属性指回函数
//普通函数来说的prototype属性没有任何用处,而构造函数的prototype属性非常有用
//构造函数的prototype属性是它的实例的原型
![在这里插入图片描述](https://img-blog.csdnimg.cn/5113880940ff44fd808c6cfcb1461713.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dkYWR3YTU2NQ==,size_16,color_FFFFFF,t_70#pic_center)
//什么是构造函数
//用new调用一个函数,这个函数就被称为“构造函数”,任何函数都可以是构造函数,只需要用new调用它
//顾名思义,构造函数用来“构造新对象”,它内部的语句将为新对象添加若干属性和方法,完成对象的初始化
//构造函数必须用new关键字调用,否则不能正常工作,正因如此,开发者约定构造函数命名时首字母要大写
//构造函数中的this不是函数本身
//什么是prototype
// 任何函数都有prototype属性,prototype是英语“原型”的意思
// prototype属性值是个对象,它默认拥有constructor属性指回函数
//普通函数来说的prototype属性没有任何用处,而构造函数的prototype属性非常有用
//构造函数的prototype属性是它的实例的原型
// 原型链查找
// JavaScript规定:实例可以打点访问它的原型的属性和方法,这被称为“原型链查找”
// function People(name,age, sex) {
// this.name = name;
// this.age = age;
// this.sex = sex;
// }
// People.prototype.nationality = '中国'; 在构造函数的prototype上 添加nationality属性
// var xiaoming = new People('小明',12,'男');
// console.log(xiaoming.nationality); 实例可以打点访问原型的属性和方法
//原型链的遮蔽效应
// function People(name, age, sex) {
// this.name = name;
// this.age = age;
// this.sex = sex;
// }
// 往原型上添加nationality属性
// People.prototype.nationality = '中国';
//
// 实例化
// var xiaoming = new People('小明', 12, '男');
// var tom = new People('汤姆', 10, '男');
// tom.nationality = '美国';
//
// console.log(xiaoming.nationality); // 中国
// console.log(xiaoming);
//
// console.log(tom.nationality); // 美国
//
// 'nationality' in xiaoming // true
// hasOwnProperty
// hasOwnProperty方法可以检查对象是否真正“自己拥有”某属性或者方法
// xiaoming.hasOwnProperty( ' name ' ) // true
// xiaoming.hasOwnProperty( 'age ' );
// xiaoming.hasOwnProperty( ' sex ' );// true
// xiaoming.hasOwnProperty( 'nationality ' );// false
// in
// in运算符只能检查某个属性或方法是否可以被对象访问,不能检查是否是自己的属性或方法
// 'name' in xiaoming true
// 'age' in xiaoming true
// 'sex' in xiaomin true
// 'nationality' in xiaomi true
// 之前,我们将方法写到了对象身上 方法直接添加 到实例身上
// function People(name,age, sex) {
// this.name = name;
// this.age = age;this.sex = sex;
// this.sayHello = function ()
// console.log('我是’+ this.name ) ;
// };
// }
把方法直接添加到实例身上的缺点:每个实例和每个实例的方法函数都是内存中不同的函数,造成了内存的浪费
解决办法:将方法写到prototype上
// // 方法要写到prototype上
// function People(name,age, sex) {
// this.name = name;
// this.age = age;
// this.sex = sex;
// }
// People.prototype.sayHello = function (){
// console.log( '我是'+ this.name);
// };
// People.prototype.sleep = function () {
// console.log(this.name + '开始睡觉,ZzZz');
// };
继承没弄明白 抽空看
// 什么是包装类
// Number()、String()和Boolean()分别是数字、字符串、布尔值的“包装类”
// 很多编程语言都有“包装类”的设计,包装类的目的就是为了让基本类型值可以从它们的构造函数的prototype上获得方法
// 案例:
// var a = new Number(123);
// var b = new String('慕课网');
// var c = new Boolean(true);
//
// console.log(a);
// console.log(typeof a); // object
// console.log(b);
// console.log(typeof b); // object
// console.log(c);
// console.log(typeof c); // object
//
// console.log(5 + a); // 128
// console.log(b.slice(0, 2)); // '慕课'
// console.log(c && true); // true
//
// var d = 123;
// console.log(d.__proto__ == Number.prototype); // true
//
// var e = '慕课网';
// console.log(e.__proto__ == String.prototype); // true
// console.log(String.prototype.hasOwnProperty('toLowerCase')); // true
// console.log(String.prototype.hasOwnProperty('slice')); // true
// console.log(String.prototype.hasOwnProperty('substr')); // true
// console.log(String.prototype.hasOwnProperty('substring')); // true
// 包装类知识总结
// Number().String()和Boolean()的实例都是object类型,它们的PrimitiveValue属性存储它们的本身值
// new出来的基本类型值可以正常参与运算
// 包装类的目的就是为了让基本类型值可以从它们的构造函数的prototype上获得方法
// 已经学习过的Math对象的方法
// 幂和开方:Math.pow()、Math.sqrt()
// 向上取整和向下取整:Math.ceil()、Math.floor()
// 四舍五入Math.round()
// Math.round()可以将一个数字四舍五入为整数
// console.log(Math.round( 3.4));
// console.log(Math.round(3.5));
// console.log(Math.round( 3.98));
// console.log(Math.round(3.49));
// Math.max()和Math.min()
// Math.max()可以得到参数列表的最大值
// Math.min()可以得到参数列表的最小值
// console.log(Math.max(6,2,9,4)); //9
// console.log(Math.min(6,2,9,4)); //2
// 如何利用Math.max()求数组最大值
// Math.max(()要求参数必须是“罗列出来”,而不能是数组
// 还记得apply方法么?它可以指定函数的上下文,并且以数组的形式传入“零散值”当做函数的参数
// var arr = [3,6,9,2];
// var max = Math.max.apply(null,arr);
// console.log(max ) ;
// 随机数Math.random()
// Math.random()可以得到0~1之间的小数
// 为了得到[a, b]区间内的整数,可以使用这个公式:
// parseInt(Math.random() *(b - a + 1)) + a
// Date()日期对象
// 使用new Date()即可得到当前时间的日期对象,它是object类型值
// 使用new Date(2020,11,1)即可得到指定日期的日期对象,主意第二个参数表示月份,从0开始算,11表示12月
// 也可以是new Date( '2020-12-01')这样的写法
// 日期对象的常见的方法
// 方法 功能
// getDate() 得到日期1~31
// getDay() 得到星期0~6
// getMonth() 得到月份0~11
// getFullYear() 得到年份
// getHours() 得到小时数0~23
// getMinutes() 得到分钟数0~59
// getSeconds() 得到秒数0~59
// 时间戳
// 时间戳表示1970年1月1日零点整距离某时刻的毫秒数
// 通过getTime()方法或者Date.parse()函数可以将日期对象变为时间戳
// 通过new Date(时间戳)的写法,可以将时间戳变为日期对象
// 日期对象
// var d = new Date();
//
// 显示时间戳的两种方法。时间戳表示1970年1月1日距离此时的毫秒数
// var timestamp1 = d.getTime(); // 精确到毫秒
// var timestamp2 = Date.parse(d); // 精确到秒,也是毫秒数,只不过最后三位一定是000
//
// console.log(timestamp1);
// console.log(timestamp2);
//
// 如何把时间戳,比如1601536565000变回日期对象呢?
// var dd = new Date(1601536565000);
// console.log(dd);
// console.log(dd.getFullYear());
对象的知识点补充
最新推荐文章于 2024-09-04 19:23:53 发布