day-01
1.对象的创建
var obj = {
// 键:值对(属性:属性值)
name: "小好",
age: 18,
gender: "男"
}
console.log(obj);
2.利用0bject构造函数
var obj2 = new Object();
obj2.name = "小谷";
obj2.age = 18;
obj2['gender'] = "女";
console.log(obj2);
3.利用自定义构造函数
function Person(name, age, gender) {
// this - 实例化对象
this.name = name;
this.age = age;
this.gender = gender;
}
var obj3 = new Person("张三", 19, "男");
console.log(obj3);
4.Object.keys
<body>
<script>
// 3.利用自定义构造函数
function Person(name, age, gender) {
// this - 实例化对象
this.name = name;
this.age = age;
this.gender = gender;
this.say = function () {
console.log("yer night rain");
};
}
var obj3 = new Person("张三", 19, "男");
console.log(obj3);
// Object.keys(obj)
// 该方法会将一个给定对象自身的可枚举的属性添加到一个数组里面进行返回
var rel = Object.keys(obj3);
console.log(rel);
</script>
</body>
</html>
5.Object.getOwnPropertyName
Object.getOwnPropertyNames(obj)方法
该方法返回一个由指定对象的所有自身属性的属性名组成的数组。
<body>
<script>
// 3.利用自定义构造函数
function Person(name, age, gender) {
// this - 实例化对象
this.name = name;
this.age = age;
this.gender = gender;
this.say = function () {
console.log("yer night rain");
};
}
var obj3 = new Person("张三", 19, "男");
var rel = Object.getOwnPropertyNames(obj3);
console.log(rel);
</script>
</body>
</html>
6.检查对象的属性是否存在
<script>
// 3.利用自定义构造函数
function Person(name, age, gender) {
// this - 实例化对象
this.name = name;
this.age = age;
this.gender = gender;
this.say = function () {
console.log("yer night rain");
};
}
var obj3 = new Person("张三", 19, "男");
console.log(obj3);
// if (obj3.name) {
// console.log("存在");
// } else {
// console.log('不存在');
// }
// in 在 。。。里面
console.log('name' in obj3);
console.log('age' in obj3);
console.log('gender' in obj3);
var arr = [1, 2, 3, 5, 6, 67];
console.log(2 in arr);
</script>
7.删除对象的属性
需要用到delete这个关键字删除对象的属性
<script>
// 3.利用自定义构造函数
function Person(name, age, gender) {
// this - 实例化对象
this.name = name;
this.age = age;
this.gender = gender;
this.say = function () {
console.log("yer night rain");
};
}
var obj3 = new Person("张三", 19, "男");
obj3.name = null;
delete obj3.name
console.log(obj3);
</script>
8.对象的数据属性和访问器属性
对象的属性分为两种
数据属性:用来存放一个值或是一组数据
访问器属性:不包含值,而是定义了一个get函数和set函数 当读取属性时 get会调用 设置属性时 set会调用
<script>
var obj = {
// 数据属性
name: '张三',
age: 17,
// 访问器属性
get getName() {
console.log("属性被访问了");
if (this.age >= 18) {
return this.name
} else {
return null;
}
},
set setName(value) {
console.log("属性被修改了");
if (this.age >= 18) {
this.name = value;
} else {
alert("您当前没有权限~")
}
}
}
// 访问属性
console.log(obj.getName);
// 设置属性
obj.setName = "普京"
console.log(obj);
var obj2 = {
name: '小好',
age: 18
}
</script>
9.案例
<body>
<div class="box"></div>
<input type="text" class="input">
<script>
var box = document.querySelector(".box");
var input = document.querySelector(".input");
input.oninput = function () {
// 修改对象属性
obj.setText = this.value;
// 访问对象属性
box.innerText = obj.getText;
}
// 让当前obj 作为媒介 监听 值的修改和访问这样程序员就能 监听
// 也为了代码的后期维护
var obj = {
text: "",
// 访问器属性
get getText() {
console.log("属性被访问了");
return this.text;
},
set setText(value) {
console.log("属性被修改了");
this.text = value;
}
}
</script>
</body>
</html>
10.对象的属性特征
<script>
var obj = {
name: '郭德纲',
age: 50,
gender: '男'
}
// 用来配置对象属性的特征信息
// Object.defineProperty(obj, prop, descriptor)
// obj:目标对象
// prop:要修改的属性
// descriptor : 修改当前属性的特征
console.log(obj);
// 地饭泡泡忒
Object.defineProperty(obj, 'gender', {
// configurable : 是否可被删除
// enumerable : 是否可被枚举
// writable : 是否可被修改
// value :当前值
// 康菲个弱bou
configurable: true,
// 欸牛么瑞bou
enumerable: true,
// ruai特bou
writable: true,
// value: "男"
})
obj.gender = "女"
delete obj.gender
console.log(obj);
for (var key in obj) {
console.log(obj[key]);
}
</script>
11.修改多个属性特征
<script>
var obj = {
name: '缪宗峰',
age: 25,
gender: '男'
}
// 用来配置对象属性的特征信息
// Object.defineProperties(obj, prop)
// 地饭泡泡忒s
Object.defineProperties(obj, {
// 生日
birthDay: {
// 是否可被删除
// 是否可以被枚举
// 是否可被修改
// vlaue
configurable: false,
enumerable: false,
writable: false,
value: '光绪21年'
},
// 职业
occupation: {
configurable: true,
enumerable: true,
writable: true,
value: "战士"
}
})
for (var k in obj) {
console.log(obj[k]);
}
12.获取属性特征
<script>
var obj = {
name: '缪宗峰',
age: 25,
gender: '男'
}
// 用来配置对象属性的特征信息
// Object.defineProperties(obj, prop)
Object.defineProperties(obj, {
// 生日
birthDay: {
// 是否可被删除
// 是否可以被枚举
// 是否可被修改
// vlaue
configurable: false,
enumerable: false,
writable: false,
value: '光绪21年'
},
// 职业
occupation: {
configurable: true,
enumerable: true,
writable: true,
value: "战士"
}
})
// Object.getOwnPropertyDescriptor(obj, prop)
// 返回目标对象内部的某一个属性的特征 返回值是一个对象
// obj:目标对象
// prop:目标对象内的某个属性
// 盖特奥嗯泡泡忒迪斯科瑞普特
var rel = Object.getOwnPropertyDescriptor(obj, 'birthDay');
var rel2 = Object.getOwnPropertyDescriptor(obj, 'name');
console.log(rel);
console.log(rel2);
// Object.getOwnPropertyDescriptors(obj)
// 返回当前对象内部所有属性的 特征 返回值是一个对象
// obj:目标对象
// 盖特奥嗯泡泡忒迪斯科瑞普特s
var rel3 = Object.getOwnPropertyDescriptors(obj);
console.log(rel3);
</script>
day-02
1.构造函数和普通函数
普通函数--主要用来封装 处理业务逻辑
function fun(形参){
代码块
this(window)
arguments(参数集合-伪数组)
}
fun(实参);
<script>
function sum() {
var sum = 0;
for (var i = 0; i < arguments.length; i++) {
sum += arguments[i];
}
return sum;
}
var rel = sum(1, 2, 3, 5, 5, 6, 6, 7);
console.log(rel);
</script>
构造函数--批量实例化对象
<script>
function Create(name, age, gender) {
// this--实例化对象
// arguments
this.name = name;
this.age = age;
this.gender = gender
}
var per = new Create("小谷", 18, "男");
console.log(per);
</script>
2.构造函数的实例成员和静态成员
01.实例成员-在构造函数内部添加的成员 只能通过实例化对象访问
02.静态成员-在构造函数本身上添加的成员--只能通过构造函数访问
<body>
<script>
function Person(name, age, gender) {
this.name = name;
this.age = age;
this.gender = gender;
this.singaSon = function () {
console.log("大碗宽面");
}
}
var rel = new Person("大碗哥", 18, "男");
var rel2 = new Person("大碗哥2", 18, "男");
// rel.singaSon = function () {
// console.log("大碗宽面");
// }
// rel2.singaSon = function () {
// console.log("大碗宽面");
// }
Person.height = "190cm";
// [[Prototype]] 对象的原型
// constructor 构造函数 - Person
console.log(Person.height);
console.log(rel.height);
console.log(rel);
console.log(rel.name);
console.log(rel.age);
console.log(rel.gender);
console.log(rel.singaSon);
</script>
</body>
3.构造函数的原型
JS规定每一个构造函数都有一个属性叫prototype它是一个对象称为构造函数的原型对象
<script>
function Create(name, age, gender) {
// this--实例化对象
// arguments
this.name = name;
this.age = age;
this.gender = gender;
// this.rap = function () {
// console.log("临时抱佛脚");
// }
}
Create.prototype.rap = function () {
console.log("临时抱佛脚");
}
var per = new Create("小谷", 18, "男");
var per2 = new Create("小谷2", 18, "男");
var per3 = new Create("小谷2", 18, "男");
var per4 = new Create("小谷2", 18, "男");
var per5 = new Create("小谷2", 18, "男");
var per6 = new Create("小谷2", 18, "男");
console.log(per);
console.log(per2);
per.rap();
per2.rap();
console.log(Create.prototype);
</script>
</body>
4.对象原型
原型:
每一个构造函数都有一个prototype属性是原型对象
每一个对象都一个__proto__ 称为 对象的原型
原型链:
对象在查找一个属性的时候,会先在自身查找,如果没有找到
就会在对象的原型(__proto__ )上查找就是构造函数的prototype
如果还没有找到就会去构造函数的prototype 的__proto__身上查找
直到查找到Object 这样一层一层向上查找形成一个链式结构称为原型链
最后没找到 返回 null 控制台打印的是undefined
<script>
function Create(name, age, gender) {
// this--实例化对象
// arguments
this.name = name;
this.age = age;
this.gender = gender;
// this.rap = function () {
// console.log("临时抱佛脚");
// }
}
Create.prototype.rap = function () {
console.log("临时抱佛脚");
}
var per = new Create("小谷", 18, "男");
var per2 = new Create("小谷2", 18, "男");
console.log(Create.prototype);
// Create.prototype.__proto__ 指向Object
console.log(per);
</script>
5.构造函数constructor
<script>
function Create(name, age, gender) {
// this--实例化对象
// arguments
this.name = name;
this.age = age;
this.gender = gender;
// this.rap = function () {
// console.log("临时抱佛脚");
// }
}
Create.prototype.rap = function () {
console.log("临时抱佛脚");
}
var per = new Create("小谷", 18, "男");
per.height = "178cm";
console.log(per);
// #### Object.prototype.hasOwnProperty(prop)方法
// 可以判断一个属性定义在对象本身而不是继承原型链的方法,
// 主要用于判断某个对象中是否有某个属性,返回值为布尔值。
// console.log(Object.prototype.hasOwnProperty('name'));
console.log(per.hasOwnProperty('name'));
console.log(per.hasOwnProperty('height'));
console.log(per.hasOwnProperty('rap'));
// #### Object.prototype.isPrototypeOf(Object)方法
// isPrototypeOf方法接收一个对象,
// 用来判断当前对象是否在传入的参数对象的原型链上,
// 返回一个布尔值。
var date = new Date();
console.dir(date);
var reg = new RegExp();
var num = new Number();
var obj = {
name: "123"
}
console.log(date.isPrototypeOf(Object));
console.log(reg.isPrototypeOf(Object));
console.log(num.isPrototypeOf(Object));
console.log(obj.isPrototypeOf(Object));
console.log(Object.prototype.isPrototypeOf(date));
console.log(Object.prototype.isPrototypeOf(reg));
console.log(Object.prototype.isPrototypeOf(num));
console.log(Object.prototype.isPrototypeOf(obj));
</script>
6.在构造函数身上封装方法
上码
<script>
// Array 数组构造函数
Array.prototype.sum = function () {
var rel = 0;
console.log(this);
for (var i = 0; i < this.length; i++) {
rel += this[i];
}
return rel;
}
var arr = [1, 2, 3, 4, 5, 5, 6, 7, 8];
var arr2 = [67, 89, 45, 32, 2, 13, 41, 3, 345, 36, 456, 5];
console.log(arr.sum());
console.log(arr2.sum());
// 商品 方法
Object.prototype.formatting = function () {
console.log(this);
if (this.price.includes("¥")) {
console.log(1);
return
} else {
// replace(target,newStr)
// this.price.replace()
this.price = "¥" + this.price
}
return this.price
}
var obj = {
title: "小米手机",
msg: "为发烧而生",
price: "678"
}
var obj2 = {
title: "好谷",
msg: "让河南学子创造中国互联网未来",
price: "¥985"
}
console.log(obj.formatting());
console.log(obj);
// ¥
</script>
day-03
1.this指向
- 普通函数this在非严格模式下指向window,严格模式下指向undefined
- 构造函数this指向实例对象,原型对象里面的方法也指向实例对象
- 对象方法中的this指向该方法所属的对象
- 事件绑定方法中的this指向绑定该事件的对象
- 定时器函数的this指向window
- 立即执行函数中的this指向window
构造函数原型对象上的函数 this指向实例化对象
2.改变this指向---call
①call会立即调用函数
②参数传递的方式是以逗号隔开
③可以改变this指向
<body>
<script>
var obj = {
name: "周孝魁",
age: 89
}
function sum(a, b) {
console.log(this);
console.log(a + b);
console.log(this.age + a + b);
}
// sum(obj.age, 1000)
console.dir(sum);
// call():使用一个指定的 `this` 值调用一个函数
// (简单理解为调用函数的方式,但是它可以改变函数的 this 指向)
sum.call(obj, 200, 200);
</script>
</body>
改变this指向---apply
①apply会立即调用函数
②传入参数是以数组形式
③改变this指向
<body>
<script>
var obj = {
name: "周孝魁",
age: 89
}
function sum(a, b) {
console.log(this);
// console.log(a + b);
console.log(this.age + a + b);
}
// sum(obj.age, 1000)
console.dir(sum);
// sum(1, 2)
sum.apply(obj, [65, 78])
</script>
</body>
改变this指向---bind
①bind不会立即调用 需要手动调用
②传入参数以逗号隔开
③改变this指向
<script>
var obj = {
name: "周孝魁",
age: 89
}
function sum(a, b) {
console.log(this);
// console.log(a + b);
console.log(this.age + a + b);
}
// sum(obj.age, 1000)
console.dir(sum);
// 在这一行bind只是把sum函数内部的this指向改变了
// 并没有直接调用sum
var rel = sum.bind(obj, 45, 60);
console.log(rel);
</script>
</body>
3.call应用场景检测数据类型
1.typeof 检测基本数据类型
2.instanceof 检测复杂数据类型
3.constructor 检测构造函数类型
4.Object.prototype.toString.call() 最精准的检测方式
<body>
<script>
var num = 100;
var str = "123"
var arr = [1, 2, 3, 4];
var obj = {
name: "小谷"
}
function fun() {
}
// 1.typeof 检测基本数据类型
console.log(typeof num);
console.log(typeof str);
console.log(typeof null);
console.log(typeof undefined);
console.log(typeof true);
console.log(typeof arr);
console.log(typeof obj);
console.log(typeof fun);
// 2.instanceof
console.log(new Date instanceof Object);
console.log(new RegExp instanceof Object);
console.log(num instanceof Object);
console.log(fun instanceof Function);
console.log(arr instanceof Array);
var date = new Date();
console.dir(date.constructor)
// 3.constructor
console.log(obj.constructor == Object);//true
console.log(date.constructor == Date);//true
// 4.Object.prototype.toString.call 最精准的检测方式
console.log(Object.prototype.toString());
console.log(Object.prototype.toString.call(123));
console.log(Object.prototype.toString.call(arr));
console.log(Object.prototype.toString.call(fun));
console.log(Object.prototype.toString.call(new Date));
console.log(Object.prototype.toString.call(new RegExp));
function typeData(data) {
// console.log(Object.prototype.toString.call(data));
var rel = Object.prototype.toString.call(data);
rel = rel.split(" ")[1].replace(']', '')
// console.log(rel.split(" ")[1].replace(']',''));
return rel
}
console.log(typeData("123"));
console.log(typeData(undefined));
console.log(typeData(null));
</script>
</body>
4.apply应用场景
<script>
console.log(Math)
// 求最大值
// Math.max
var rel = Math.max(1, 2, 3, 5, 5, 6, 7,);
console.log(rel);
var arr = [56, 66, 2, 11, 67, 45];
var rel2 = Math.max.apply(Math, arr);
console.log(rel2);
</script>
4.bind应用场景 案例
<body>
<button>5秒之后再次点击</button>
<button>5秒之后再次点击</button>
<button>5秒之后再次点击</button>
<button>5秒之后再次点击</button>
<button>5秒之后再次点击</button>
<script>
var btn = document.querySelectorAll("button");
// var timerId = null;
for (var i = 0; i < btn.length; i++) {
btn[i].onclick = function () {
this.disabled = true;
var num = 5;
var timerId = setInterval(function () {
num--;
if (num <= 0) {
this.disabled = false;
this.innerText = "5秒之后再次点击";
clearInterval(timerId);
} else {
this.innerText = num + "秒之后再次点击";
}
}.bind(this), 1000);
}
}
// .bind(xx,xx)
</script>
5.定时器传参
解决定时器不能传参的问题
在外部封装函数 写在定时器方法里面进行调用
注意:要用引号将函数包括
<script>
var k = 100;
setTimeout("fun(k)", 2000);
function fun(i) {
console.log(k);
}
setTimeout(function () {
}, 1000)
// for (var i = 0; i < 10; i++) {
// console.log(i);
// }
</script>
</body>
6.forEach数组的操作方法
<body>
<script>
var arr = [1, 2, 3, 5, 6, 7, 89];
// 遍历数组
var rel = arr.forEach(function (value, index, arr) {
// value当前元素
// index元素的索引
// arr当前数组
console.log(value + "-----" + index);
console.log(arr);
return "操作元素" + value
})
console.log(rel);
// undefined
// forEach没有返回值
// function fun() {
// arguments.forEach(function (v) {
// console.log(v);
// })
// }
// fun(1, 2, 3, 4, 5, 65, 6, 7)
</script>
</body>
7.map数组的操作方法
<script>
var arr = [1, 2, 3, 5, 6, 7, 89];
// 遍历数组
var rel = arr.map(function (value, index, arr) {
// value当前元素
// index元素的索引
// arr当前数组
console.log(value + "-----" + index);
console.log(arr);
return "操作元素" + value
})
console.log(rel);
console.log(arr);
// map 具有返回值
// 注意:map() 不会对空数组进行检测, map() 不会改变原始数组。
</script>
</body>
8.filter数组的操作方法 案例
<body>
<button class="btn">点击筛选</button>
<ul class="list">
</ul>
<script>
var btn = document.querySelector(".btn");
var list = document.querySelector(".list");
var arr = [56, 32, 78, 11, 23, 103, 45];
// filter 过滤 方法创建一个数组,将满足条件的元素添加到新数组中返回
var rel = arr.filter(function (value, index, arr) {
// value当前元素
// index元素的索引
// arr当前数组
console.log(value);
// 具有返回值
return value > 50
})
console.log(rel);
var goodsList = [
{
title: "东北大米",
msg: "goodgoods",
price: 40
}, {
title: "红富士苹果",
msg: "just so so",
price: 80
}, {
title: "苞谷",
msg: "拜亚 拜亚 拜亚",
price: 1000
}, {
title: "葡萄",
msg: "甜",
price: 105
}, {
title: "杨桃",
msg: "塞拉啦",
price: 267
}
]
goodsList.forEach(function (v) {
list.innerHTML += `
<li>
名称 ${v.title}
介绍 ${v.msg}
价格 ${v.price}
</li>
`
})
btn.onclick = function () {
list.innerHTML = ""
var rel = goodsList.filter(function (v) {
return v.price > 100
})
console.log(rel);
rel.forEach(function (v) {
list.innerHTML += `
<li>
名称 ${v.title}
介绍 ${v.msg}
价格 ${v.price}
</li>
`
})
}
</script>
</body>
9.some数组的操作方法
<script>
var arr = [56, 32, 78, 11, 23, 103, 45, 103];
// some 查找数组中是否有满足条件的元素 ,如果数组中有元素满足条件返回 true,否则返回 false。
var rel = arr.some(function (v) {
return v > 100
})
console.log(rel);
</script>
10.every数组的操作方法
<script>
var arr = [56, 32, 78, 11, 23, 103, 45, 103];
// every() 方法用于检测数组所有元素是否都符合指定条件(通过函数提供)。
var rel = arr.every(function (v) {
console.log("zhixing");
return v < 100
// 如果数组中检测到有一个元素不满足,则整个表达式返回false,且剩余的元素不会再进行检测。
// 所有元素都满足条件 才会返回true
})
console.log(rel);
</script>
11.fiind数组的操作方法
<script>
var arr = [56, 32, 78, 11, 23, 103, 45, 103];
// find() 方法返回通过测试(函数内判断)的数组的第一个元素的值。
// find() 方法为数组中的每个元素都调用一次函数执行:
// 如果没有符合条件的元素返回 undefined
var rel = arr.find(function (v) {
console.log("执行");
return v > 100
})
console.log(rel);
</script>
12.reduce数组的操作方法
<script>
// reduce方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。
// array.reduce(function (total, value, index, array) {
// - total 必需。初始值, 或者计算结束后的返回值。
// value 必需。当前元素
// index 可选。当前元素的索引
// array可选。当前元素所属的数组对象。
// - initialValue 作为第一次调用 `callback`函数时的第一个参数的值。 如果没有提供初始值,则将使用数组中的第一个元素。
// }, initialValue)
// 求和
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
var rel1 = arr.reduce(function (total, value) {
// console.log(total);
// console.log(value);
return total + value
})
console.log(rel1);
// 求最大值
var arr2 = [45, 67, 12, 2, 103, 44, 33];
var rel2 = arr2.reduce(function (total, value) {
// if (total < value) {
// total = value;
// }
return Math.max(total, value);
})
console.log(rel2);
// 数组去重
// splice push()
var arr3 = [44, 65, 44, 12, 3, 2, 5, 2, 16];
var rel3 = arr3.reduce(function (total, value, index) {
// []
if (!total.includes(value)) {
total.push(value);
}
return total;
}, [])
console.log(rel3);
arr3.sort(function (a, b) {
return a - b;
})
console.log(arr3);
</script>
day-04
1.构造函数继承
父构造函数
<script>
function Father(name, age, gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
var father = new Father("小头爸爸", 50, "男");
console.log(father);
</script>
子构造函数
<script>
function Son(name, age, gender) {
// 让子构造函数继承父构造函数的属性
Father.call(this, name, age, gender);
console.log(this);
}
var son = new Son("大头儿子", 31, "男");
</script>
2.原型对象继承
<script>
// 父构造函数
function Father(name, age, gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
Father.prototype.makeMoney = function () {
console.log("疯狂挣钱");
}
var father = new Father("小头爸爸", 50, "男");
console.log(father);
// 子构造函数
function Son(name, age, gender) {
// 让子构造函数继承父构造函数的属性
Father.call(this, name, age, gender);
// console.log(this);
}
// 原型继承 如果直接使用原型对象赋值的方式 继承 那么两个对象会指向同一个数据
// 修改其中一个 另一个也会被修改 大咩
// Son.prototype = Father.prototype;
Son.prototype = new Father();
// constructor 只能指向自己本身
// 所以这里必须要多一步 让son的constructor 指回自己本身
Son.prototype.constructor = Son;
Son.prototype.spendMoney = function () {
console.log("他喜欢在设计师服装和豪华度假上花钱。;");
}
var son = new Son("大头儿子", 31, "男");
console.log(son);
</script>
3.Object.create
<script>
function Fun(height) {
this.height = height;
}
var p1 = new Fun("180cm");
console.log(p1);
// Object.create()
// 该方法用创建对象
// 第一个参数 是 以谁为原型创建新的对象
// 第二个参数 传入一个对象用来设置 新对象的值和属性特征
var newObj = Object.create(p1, {
name: {
configurable: true,
enumerable: true,
writable: true,
value: "迪丽热巴"
},
age: {
configurable: true,
enumerable: true,
writable: true,
value: 20
}
})
console.log(newObj);
console.log(newObj.height);
</script>
4.Object.create实现继承
<script>
// 父构造函数
function Father(name, age, gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
Father.prototype.makeMoney = function () {
console.log("疯狂挣钱");
}
var father = new Father("小头爸爸", 50, "男");
console.log(father);
// 子构造函数
function Son(name, age, gender) {
// 让子构造函数继承父构造函数的属性
Father.call(this, name, age, gender);
// console.log(this);
}
Son.prototype = Object.create(father);
// 将constructor 指回自身
Son.prototype.constructor = Son;
var son = new Son("大头儿子", 31, "男");
console.log(son);
son.makeMoney()
</script>
5.严格模式
<script>
// 为全局脚本开启严格模式
"use strict";
// 1.在严格模式下声明变量必须要写关键字var
// num = 100;
// console.log(num);
// 2.不允许删除变量
// var num = 100;
// delete num;
// 3.严格模式下全局作用域中函数中的 this 是 undefined
function fn() {
console.log(this);
}
fn();
function Person() {
this.sex = '男';
}
// Person();严格模式下,如果 构造函数不加new调用, this 指向的是undefined 如果给他赋值则 会报错.
// var p1 = new Person();
// console.log(p1.sex);
// Person()
</script>
<script>
// num = 100;
// console.log(num);
function Person() {
this.sex = '男';
console.log(this);
}
Person()
</script>
<script>
function fun() {
// 为函数开启严格模式
"use strict";
}
</script>
</body>
6.高阶函数
<script>
// 高阶函数
// 函数作为参数
function fun(fun) {
console.log(fun);
// 函数作为返回值
return fun2(10,20);
}
function fun2(num1, num2) {
return num1 + num2;
}
var rel = fun(fun2);
console.log(rel);
</script>
7.闭包
<script>
// 内部函数可以访问外部函数的参数和变量 形成的词法环境叫做闭包
var num = 100;
function fun(a) {
var num = 200;
function fun2() {
//作用域链
console.log(a);
console.log(num);
}
fun2();
}
fun(123)
// console.log(num2);
// 如何从函数外部读取函数内部的变量
// 闭包 是一个思想
// 在代码的任何地方随处可见
</script>
</body>
8.闭包案例tab切换
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.content {
width: 800px;
height: 800px;
border: 1px solid red;
margin: 100px auto;
}
.content .tab {
width: 100%;
height: 50px;
display: flex;
border-bottom: 1px solid skyblue;
}
.content .tab div {
flex: 1;
height: 50px;
text-align: center;
line-height: 50px;
border-right: 1px solid skyblue;
}
.content .tab div:last-child {
border-right: 0px;
}
.active {
color: red;
}
.detail {
width: 100%;
height: 749px;
}
.detail div {
width: 100%;
height: 100%;
display: none;
}
.detail .active-box {
display: block;
}
</style>
</head>
<body>
<div class="content">
<div class="tab">
<div class="active">首页</div>
<div>详情</div>
<div>发现</div>
<div>我的</div>
</div>
<div class="detail">
<div class="active-box">首页内容</div>
<div>详情内容</div>
<div>发现内容</div>
<div>我的内容</div>
</div>
</div>
<script>
var tabs = document.querySelectorAll(".tab div");
var details = document.querySelectorAll(".detail div");
function slibings(ele) {
for (var i = 0; i < ele.length; i++) {
ele[i].className = "";
}
}
// tabs.forEach()
for (var i = 0; i < tabs.length; i++) {
(function (k) {
// 利用闭包存储变量
tabs[k].onclick = function () {
console.log(k);
slibings(tabs)
tabs[k].className = "active";
}
})(i)
}
// 闭包
// 函数嵌套函数 内部函数可以访问外部函数变量或参数 形成的此法环境叫做闭包
// 特性
// 函数套函数
// 内部函数可以访问外部函数的参数和变量
// 使变量长期驻扎在内存当中
// 优点
// 使变量长期驻扎在内存当中
// 内部函数可以访问外部函数的参数和变量
// 缺点
// 使用不当会造成内存泄露
</script>
</body>
</html>
9.递归
<script>
// 递归:让函数在内部自己调用自己
// var num = 0;
function fun(num) {
num++;
console.log(num);
if (num == 6) {
// 递归必须要加退出条件
return num
} else {
fun(num);
}
}
fun(1);
//递归求阶乘
function sum(num) {
// console.log(num - 1);
if (num == 1) {
return 1;
} else {
// 13 * sum(12)
return num * sum(num - 1);
}
}
var rel = sum(4);
console.log(rel);
</script>
10.抚平数组
<script>
// 多维转一维
var arr = [1, 2, 3, [4, 5, 6, [7, 8, 9, [10, 11, 12]]]]
// Array.isArray();
// var relarr = [];
function flatArr(data, relArr) {
// []
// [1]
// [1,2]
// [1,2,3]
relArr = relArr || [];
// console.log(relArr);
// 2.将多维数组进行遍历
data.forEach(function (v) {
// 3.判断当前元素如果是一个数组
if (Array.isArray(v)) {
// 4.利用递归 再次调用自己并将当前数组再次传入函数
flatArr(v, relArr);
} else {
// 5.如果当前元素不是数组 那么将添加到新数组内
relArr.push(v);
}
})
return relArr;
}
// 1.调用函数传入多维数组
var rel = flatArr(arr);
console.log(rel);
// || 左右两个操作数 只要有一个结果为true 那么整体结果就是true
// 如果说第一个操作数为假则返回第二个操作数
// console.log(false || true);
// console.log('' || 123);
// // console.log(num || []);
// var a = [] || a;
// console.log(a);
</script>
day-05
1.浅拷贝
<script>
var obj = {
name: "周孝魁",
age: 20,
gender: "🚹",
hobby: ["三国", "云边有个小卖部", "骆驼祥子"]
}
var obj2 = {
name: "化晨",
sayHi: function () {
console.log("to day is 八月 last day");
}
}
// 浅拷贝 : 赋值出来的对象与源对象共用同一个内存地址,存储在同一块空间
// 改变其中一个对象另一个也会改变
// 1.赋值
// var obj2 = obj;
// obj2.hobby[0] = "西游记";
// console.log(obj);
// console.log(obj2);
// 2.使用for in
// var newobj = {}
// for (var k in obj) {
// newobj[k] = obj[k];
// }
// console.log(obj);
// console.log(newobj);
// 3.使用Object.assign
// Object.assign()方法用于将所有可枚举属性的值从一个或多个源对象分配到目标对象。它将返回目标对象。
var newobj = {};
// Object.assign(target,sources)
Object.assign(newobj, obj, obj2);
console.log(newobj);
</script>
2.深拷贝
<script>
// 深拷贝:重新开辟一块空间用来存储新对象
// 与源对象不共用一块内存空间
// 递归深复制对象
var obj = {
name: "周孝魁",
age: 20,
gender: "🚹",
hobby: ["三国", "云边有个小卖部", "骆驼祥子", {
lookmovies: ["林正英", "漫威", "贞子", "釜山行", "生化危机"]
}]
}
// var newobj = {}
// // 1.递归:在函数内部自己调用自己
// function deepCopy(newobj, obj) {
// for (var k in obj) {
// // k 属性
// // obj[k] 属性值
// // 先获取属性值
// var value = obj[k];
// if (value instanceof Array) {
// console.log(value);
// console.log(k);
// newobj[k] = [];
// deepCopy(newobj[k], value)
// } else if (value instanceof Object) {
// newobj[k] = {};
// deepCopy(newobj[k], value)
// } else {
// newobj[k] = value;
// }
// }
// return newobj
// }
// deepCopy(newobj, obj);
// obj.hobby[0] = "西游记";
// obj.hobby[3].lookmovies[1] = "葫芦娃"
// console.log(newobj);
// console.log(obj)
// 2.深拷贝 使用JSON下面的两个方法
// JSON.stringify()将对象转换为json字符串格式
// JSON.parse() 将字符串转换为json对象格式
// console.log(JSON.parse(JSON.stringify(obj)));
var obj3 = JSON.parse(JSON.stringify(obj));
obj.hobby[0] = "红楼梦"
console.log(obj3);
</script>
</body>
3.类
<script>
// 创建类
class Custom {
// 类的初始化属性
constructor(name, age) {
this.name = name;
this.age = age;
}
// 定义方法
// 省略function 关键字 并且没有逗号
singsong() {
console.log("我会唱歌");
}
dance() {
console.log("我会跳舞");
}
fly() {
console.log("我会飞");
}
}
// 实例化对象
var p1 = new Custom("张万顺", 22);
console.log(p1);
p1.singsong();
</script>
4.类操作DOM元素
<style>
.box {
width: 100px;
height: 100px;
background-color: pink;
float: left;
margin-right: 20px;
}
</style>
</head>
<body>
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
<script>
class Dom {
// 初始化属性
constructor(className) {
this.box = document.querySelectorAll(className)
console.log(this);
this.init();
}
// 用来初始化事件
init() {
for (var i = 0; i < this.box.length; i++) {
this.box[i].onclick = this.logEvent
}
}
logEvent() {
console.log(this);
this.style.width = 300 + "px";
}
}
var p1 = new Dom('.box')
// var box = document.querySelectorAll(className)
// init()
// function init() {
// for (var i = 0; i < this.box.length; i++) {
// this.box[i].onclick = logEvent
// }
// }
// function logEvent() {
// console.log(this);
// this.style.width = 300 + "px";
// }
console.log(p1);
</script>
5.类的继承
<script>
class Father {
constructor(name, age, height) {
this.name = name;
this.age = age;
this.height = height;
}
makeMeony() {
console.log("疯狂赚钱");
}
}
// extends 欸柯斯ten斯 继承
class Son extends Father {
constructor(name, age, height) {
// super 使用super 方法访问父类身上的属性
super(name, age, height)
}
makeMeony(){
console.log("儿子长大了 自己赚钱");
}
}
var father = new Father("小头爸爸", 50, 180);
var son = new Son("大头儿子", 31, 170);
console.log(father);
console.log(son);
son.makeMeony()
</script>