构造函数
构造函数是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋初始值,它总与new一起使用。我们可以把对象中一些公共的属性和方法抽取出来,然后封装到这个函数里面。
new在执行时会做四件事情
- 在内存中创建一个新的空对象。
- 让this指向这个新的对象。
- 执行构造函数里面的代码,给这个新对象添加属性和方法。
- 返回这个新对象(所以构造函数里面不需要return)
静态成员和实例成员
JavaScript的构造函数中可以添加一些成员,可以在构造函数本身上添加,也可以在构造函数内部的this添加。通过这两种方式添加的成员,就分别称为静态成员和实例成员
- 静态成员 : 在构造函数本上添加的成员称为静态成员,只能由构造函数本身来访问 (Star.sex = ‘男’) 直接在构造函数上添加
- 构造函数只能通过构造函数来访问 (Star.sex)
- 实例成员 : 在构造函数内部创建的对象成员称为实例成员,只能由实例化的对象来访问 (this.uname…)
构造函数与原型
构造函数方法很好用,但是存在浪费内存的问题
构造函数原型 prototype
构造函数通过原型分配的函数是所有对象所共享的
JavaScript规定,每一个构造函数都有一个prototype属性,指向另一个对象。注意这个prototype就是一个对象,这个对象的所有属性和方法,都会被构造函数所拥有。
- 我们可以把那些不变的方法,直接定义在prototype对象上,这样所有对象的实例就可以共享这个方法。
// 构造函数和对象
// 1. 构造函数 明星 泛指的某一大类 它类似于 java 语言里面的 类(class)
function Star(uname, age, sex) {
this.name = uname;
this.age = age;
this.sex = sex;
/*this.sing = function(sang) {
console.log("我会唱歌");
}*/
}
Star.prototype.sing = function() {
console.log("我会唱歌");
}
// 2. 对象 特指 是一个具体的事物 刘德华 == {name: "刘德华", age: 18, sex: "男", sing: ƒ}
var ldh = new Star('刘德华', 18, '男'); // 调用函数返回的是一个对象
var zxy = new Star('张学友', 18, '男');
ldh.sing();
zxy.sing();
对象原型 proto
对象都会有一个属性_proto_指向构造函数的prototype原型对象,之所以我们对象可以使用构造函数prototype原型对象的属性和方法,就是因为对象有_proto_原型的存在
- proto 对象原型和原型对象 prototype 是等价的
function Star(uname, age, sex) {
this.name = uname;
this.age = age;
}
Star.prototype.sing = function() {
console.log("我会唱歌");
}
var ldh = new Star('刘德华', 18);
var zxy = new Star('张学友', 19);
ldh.sing();
console.log(ldh); //对象身上系统自己添加一个 __proto__ 指向我们构造函数的原型对象 prototype
console.log(ldh.__proto__ === Star.prototype); //true
// 方法的查找规则: 先看ldh 对象身上是否有sing方法,如果有就执行这个对象上的sing
// 若果没有sing这个方法,因为有_proto_存在,就去构造函数原型对象prototype身上去查找

constructor 构造函数
对象原型(proto)和构造函数(prototype)原型对象里面都有一个属性constructor属性,constructor我们称为构造函数,因为它指回构造函数本身
- constructor主要为了跳回到原来的构造函数
Star.prototype = {
// 如果我们修改了原来的原型对象,给原型对象赋值的是一个对象,则必须手动的利用constructor指回原来的构造函数
constructor: Star,
sing: function(){
console.log("我会唱歌");
},
movie: function(){
console.log("我会拍电影");
}
}
var ldh = new Star('刘德华', 18);
var zxy = new Star('张学友', 19);
console.log(Star.prototype.constructor);
console.log(ldh.__proto__.constructor);
构造函数,实例,原型对象三者之间的关系

原型链

查找机制: 先从对象实例开始找,然后到Star原型对象找,然后到Object原型对象上找,最后指向null。只要有一个对象有要找的东西,就返回出来。(就近原则)
this指向
- 在构造函数中,里面的this指向的是对象实例 ldh
- 在原型对象中,this指向的是实例对象
继承
call()
调用这个函数,并且修改函数运行时的this指向
// call 方法
function fn(x,y) {
console.log('我想咖啡');
console.log(this);
console.log(x,y);
}
var o = {
name: 'andy'
};
fn.call();
// call() 可以改变这个函数的this指向 此时这个函数的this 就指向了o这个对象
// 主要功能可以实现继承
fn.call(o,1,2);
子继承父的原型对象
son.prototype = new Father().proto
ES5中新增的方法
数组方法
forEach
array.forEach(function(currentValue,index,arr))
- currentValue 数组元素
- index 数组索引
- arr 数组本身
filter
主要用于筛选数组,直接返回一个新的数组
var newArray = array.filter(function(currentValue,index,arr){
return currentValue>10;
})
- currentValue 数组元素
- index 数组索引
- arr 数组本身
some
用于筛选是否有满足条件的元素,并且返回该元素
注意: 只要找到一个 就直接终止循环
var newArray = array.some(function(val){
return val>10;
})
字符串的方法
trim()
用于删除字符串中前后两端的空格,直接返回一个字符串
Object.defineProperty(obj,prop,descriptor)
用于改变属性
this
apply
fun.apply(thisArg,[array])
主要运用:
- 求数组的最大值
var arr = [1,66,3,99,4];
var max = Math.max.apply(null,arr);
console.log(max);
bind方法
不会调用函数
fun.bind(thisArg,arg1,arg2,…)
function fn(){
console.log(this);
};
var f = fn.bind(o);
f();
// 可以改变原来函数内部的this
// 返回新的函数
btn1.onclick = function(){
this.disabled = true;
setTimeout(function(){
this.disabled = false;
}.bind(this),3000); // 此时这个this指向btn
}
高阶函数
高阶函数是对其他函数进行操作的函数,它接收函数作为参数或将函数作为返回值输出。
函数也是一种数据类型,同样可以作为参数,传递给另一个参数使用。最典型的就是作为回调函数。
立即执行函数的this指向window
闭包
变量作用域
变量根据作用域的不同分为两种: 全局变量和局部变量
什么是闭包
闭包指有权访问另一个函数
一个函数里面有一个函数访问了他里面的变量,称之为闭包函数
function fn() {
var num = 10;
function fun() {
console.log(num);
}
return fun;
}
var f = fn();
f();
拷贝
Object.assign
- 浅拷贝只是拷贝一层,更深层次的对象级别的只拷贝引用。
- 只拷贝了地址
var obj = {
id: 1,
name: 'andy'
};
var o = {};
for(var k in obj){
// k 是属性名 obj[k]属性值
o[k] = obj[k];
}
// 用语法糖 浅拷贝
Object.assign(o,obj);
深拷贝
var obj = {
id: 1,
name: 'andy',
msg: {
age: 18
},
color:['pink','yellow']
};
var o = {};
function deepCopy(newobj,oldobj){
for(var k in oldobj) {
// 判断数据类型
var item = oldobj[k];
// 判断这个值是否为数组;
if (item instanceof Array) {
newobj[k] = [];
deepCopy(newobj,item);
} else if (item instanceof Object) {
// 判断是不是对象
newobj[k] = {};
deepCopy(newobj[k],item)
} else {
// 属于简单数据类型
newobj[k] = item;
}
}
}
deepCopy(o,obj);
console.log(o);
关键字
const
const必须要有初始值
const同样具有块级作用域
const声明的常量,不可更改
let
其作用域为该语句所在的代码块内,不存在变量提升
var
作用域为该语句所在的函数内,存在变量提升

数组
新的赋值方法
let ary = [1,2,3];
[a,b,c] = ary;
console.log(a);
console.log(b);
console.log(c);
拓展方法
Array.from()
let arrayLike = {
"0": 1,
"1": 2,
"length": 2
}
let newAry = Array.from(arrayLike,item=>item*2);
console.log(newAry);
Array.find()
返回第一个符合条件的元素
let ary=[{
id:1,
name: '张三'
}, {
id: 2,
name: '李四'
}];
let target = ary.find((item,index)=>item.id ==2);
console.log(target)
Array.findIndex()
跟上一个一样,不过返回的是索引
Array.includes()
表示某个数组是否包含给定的值,返回布尔值
对象解构
从对象中取出其属性赋值给变量
let ary = {name:'lisi',age:30,sex:'男'};
let { name, age, sex } = person;
console.log(name);
console.log(age);
console.log(sex);
let person = {name:'lisi',age:30,sex:'男'};
let {name: myName} = person;
console.log(myName)
箭头函数
两者一样,并且箭头函数跟lambda表达式类似
function sum(num1,num2){
return num1+num2;
}
const sum2 = (num1,num2) => {num1+num2};
- 箭头函数不绑定this,所以箭头函数中的this是定义该箭头函数的对象的this
剩余函数
const sum = (...args) =>{
let total = 0;
args.forEach(item => total += item);
return total;
};
console.log(sum(10,20));
console.log(sum(10,20,30));
拓展运算符应用
合并数组
let ary1 = [1,2,3];
let ary2 = [3,4,5];
let ary3 = [...ary1,...ary2];
console.log(ary3);
ary1.push(...ary2);
将伪数组转换为真数组
String 拓展方法
用反引号来定义的字符串,可以换行,可以简化字符串拼接 $()甚至可以调用函数,显示函数的返回值
let name = `张三`;
let sayHello = `hello,my name is ${name}`;
console.log(sayHello);
startsWith() 和 endsWith()
一个判断开头是否以参数字符串开头,一个为结尾,都返回布尔值
repeat()
一个字符串连续复制n次,返回一段字符串
Set数据结构
不能重复,跟Java的那个类似,但又跟数组类似
const s1 = new Set(["a","b"]);
console.log(s1.size);
console.log(s1);
// 去重复,返回数组
const s3 = new Set(["a","a","b","b"]);
console.log(s3.size);
const ary = [...s3];
console.log(ary);
遍历的时候 用forEach即可
871

被折叠的 条评论
为什么被折叠?



