1,执行上下文
// js引擎在代码正式执行之前会做一个预处理的工作: 1,收集变量 2,收集函数
执行上下文,上下文对象: 代码正式执行之前会进入执行环境
1, 创建变量对象:
1) 变量
2) 函数及函数的参数
3) 全局: window
4) 局部: 抽象的但是确实存在
2, 确认this 的指向
1) 全局: this ---》 window
2) 局部: this ---》 调用其的对象,
3, 创建作用域: 父级作用域链 + 当前的变量对象
4, 扩展:
ECObj = {
变量对象:{ 变量,函数,函数的形参}
scopeChain : 父级作用域链 + 当前的变量对象
this:{ window || 调用其的对象}
}
2,bind,call和apply的区别---改变this指向的方法
1、相同点: 三个函数都会改变this的指向(调用这三个函数的函数内部的this)
2、不同点:
- 1)、bind 和call一样,但是bind会产生新的函数,(把对象和函数绑定死后,产生新的函数)
- 2)、call和apply不会产生新的函数,只是在调用时,绑定一下而已。
- 3)、call和apply的区别,第一个参数都是要绑定的this,apply第二个参数是数组(是函数的所有参数),call把apply的第二个参数单列出来。
obj.myFun.call(db,'成都','上海'); // 德玛 年龄 99 来自 成都去往上海
obj.myFun.apply(db,['成都','上海']); // 德玛 年龄 99 来自 成都去往上海
obj.myFun.bind(db,'成都','上海')(); // 德玛 年龄 99 来自 成都去往上海
obj.myFun.bind(db,['成都','上海'])(); // 德玛 年龄 99 来自 成都, 上海去往 undefined
6, JS的基本数据类型和引用数据类型有哪些,两者区别
- 基本数据类型->string、number、Boolean、null、undefined、symbol
- 引用数据类型->array、object、function
- 基本数据类型是保存在栈内存中,操作的是值,改变源数据不会影响新的变量
- 引用数据类型保存在堆内存中,操作的是地址,改变其中一个会影响另一个
6,
false (布尔型)
0(数值型)
null(定义空的或者不存在,现在没有,将来可能有)
undefined(未定义,一直不存在)
NaN(不是一个有效数字)
空字符串(空字符串,字符类型)
6(兑吧)情人节福利题,如何实现一个 new
-
new 关键字调用函数的过程
首先创建一个空的对象,空对象的 ___proto____属性指向构造函数的原型对象,把创建的空对象赋值构造函数内部的this,用构造函数内部的方法修改空对象,如果构造函数返回一个非基本类型的值,则返回这个值,否则返回创建的实例化对象。使用new之后不用加括号一样会执行函数
function _new(fn, ...arg) {
var obj = Object.create(fn.prototype);
const result = fn.apply(obj, ...arg);
return Object.prototype.toString.call(result) == '[object Object]' ? result : obj;
}
6,什么是原型,什么是原型链,两者关系
- 原型(prototype):函数自带的属性,函数的实例化对象找不到某个属性或者方法,一定会去构造函数的原型下去找
- 原型链(proto):实例化对象身上自带一个属性
- 原型关系链:函数的实例化对象找不到某个属性或方法,一定会去构造函数的原型下去找,如果还没有会去原型下的原型链查找,直到找到Object.prototype为止
- 两者关系:实例化对象的原型链 === 构造函数的原型
//接下来说一下原型链
//首先明确的是函数有prototype
//对象有_proto_
//万物皆对象所以其实函数也有_proto_属性
例子:
function fn(){
this.a=1;
}
var newfn=new fn();
newfn._proto_=>fn.prototype=>_proto_=>Object.prototype=>_proto_=>null
// 原型链最顶层是Null constructor=>最终指向函数本身
1,构造函数、实例、原型三者之间的关系
// 构造函数
function Person(first, last, age, eyecolor) {
this.firstName = first;
this.lastName = last;
this.age = age;
this.eyeColor = eyecolor;
}
Person.prototype.nationality = "English"; //添加新的属性 this.nationality = "English";
Person.prototype.name = function() { // 使用 prototype 属性给添加新的方法
return this.firstName + " " + this.lastName;
};
1,构造函数(constructor):专门用来生成实例对象的函数,实例的构造函数属性(constructor)指向构造函数,
2,原型对象(prototype):就是定义所有实例对象共享的属性和方法的对象
3,prototype是构造函数访问原型对象,__proto__是对象实例访问原型对象。
4,通过构造函数得到的实例对象内部会包含一个指向构造函数的 prototype 对象的指针_proto_
- 1,每个对象都有 _proto_ 属性,但只有函数对象才有 prototype 属性,
let obj = {}
obj.__proto__ === Object.prototype // true
- 2, 函数都同时拥有__proto__和protytpe属性, 函数的__proto__指向自己的函数实现, 函数的protytpe是一个对象, 所以函数的prototype也有__proto__属性 指向Object.prototype
function func() {}
func.prototype.__proto__ === Object.prototype // true
- 3,Object.prototype.__proto__指向null,对象到原型,再到原型的原型……所有对象的原型最终都可以上溯到Object.prototype
Object.prototype.__proto__ // null
9、验证手机号码和邮箱的正则表达式
\w 查找单词字符 ------- \d 数字 ----- [^ ] 之外的所有 ----- () 整体修饰
^ 开始 $ 结尾
+: 1+,一个或更多。
*: 0+,零个或更多。
?: 0/1,零个或一个。
{1,2}: 1<=length<=2,长度。
(): 表示一个表达式的组。
[]: 匹配的字符范围,我理解为一个块,很多块放在一个组()里面。
\i 忽略大小写
// 手机号码验证
if(!(/^1(3|4|5|6|7|8|9)\d{9}$/.test(phone))){ 错误 }
// 邮箱验证
var reg = /^([a-zA-Z]|[0-9])(\w|\-)+@[a-zA-Z0-9]+\.([a-zA-Z]{2,4})$/;
if(reg.test(email)){ 。。。}
6,如何判断一个对象是否为数组
第一种方法:使用 instanceof 操作符。
第二种方法:使用 ECMAScript 5 新增的 Array.isArray()方法。
第三种方法:使用使用 Object.prototype 上的原生 toString()方法判断。
ES5的继承和ES6的继承有什么区别?
-
ES5的继承是通过prototype或构造函数机制来实现。ES5的继承实质上是先创建子类的实例对象,然后再将父类的方法添加到this上(Parent.apply(this))。
-
ES6的继承机制实质上是先创建父类的实例对象this(所以必须先调用父类的super()方法),然后再用子类的构造函数修改this。
具体为ES6通过class关键字定义类,里面有构造方法,类之间通过extends关键字实现继承。
子类必须在constructor方法中调用super方法,否则新建实例报错。因为子类没有自己的this对象,而是继承了父类的this对象,然后对其调用。如果不调用super方法,子类得不到this对象。
6,什么是原型,什么是原型链,两者关系
6,什么是原型,什么是原型链,两者关系
6,什么是原型,什么是原型链,两者关系
6,什么是原型,什么是原型链,两者关系
6,什么是原型,什么是原型链,两者关系
6,什么是原型,什么是原型链,两者关系
6,什么是原型,什么是原型链,两者关系
6,什么是原型,什么是原型链,两者关系
6,什么是原型,什么是原型链,两者关系
6,什么是原型,什么是原型链,两者关系
来源:CSDN
作者:Cookie_fzx
链接:https://blog.csdn.net/image_fzx/article/details/103960558