文末
逆水行舟不进则退,所以大家要有危机意识。
同样是干到35岁,普通人写业务代码划水,榜样们深度学习拓宽视野晋升管理。
这也是为什么大家都说35岁是程序员的门槛,很多人迈不过去,其实各行各业都是这样都会有个坎,公司永远都缺的高级人才,只用这样才能在大风大浪过后,依然闪耀不被公司淘汰不被社会淘汰。
为了帮助大家更好温习重点知识、更高效的准备面试,特别整理了《前端工程师核心知识笔记》电子稿文件。
内容包括html,css,JavaScript,ES6,计算机网络,浏览器,工程化,模块化,Node.js,框架,数据结构,性能优化,项目等等。
269页《前端大厂面试宝典》
包含了腾讯、字节跳动、小米、阿里、滴滴、美团、58、拼多多、360、新浪、搜狐等一线互联网公司面试被问到的题目,涵盖了初中级前端技术点。
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
前端面试题汇总
function Student(name,age,sex,score) {
// 直接对父类型的构造函数进行一个普通调用
// Person 普通调用过程中,内部的 this 指向的是 window
// 可以通过 call 方法更改Person 内部的 this
Person.call(this,name,age,sex);
this.score = score;
}
// 老师类型
function Teacher(name,age,sex,salary) {
Person.call(this,name,age,sex);
this.salary = salary;
}
// 创建学生的实例对象
var s1 = new Student(“zs”,18,“男”,89);
var s2 = new Student(“ls”,19,“男”,92);
console.dir(s1);
console.dir(s2);
===================================================================
// 构造函数的属性的继承
// 人类类型
function Person(name,age,sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
// 父类型的原型对象中有方法也需要继承
Person.prototype.sayHi = function () {
console.log(“你好”);
};
// 学生类型
function Student(name,age,sex,score) {
Person.call(this,name,age,sex);
this.score = score;
}
// 子类型的原型对象上,需要继承父类型原型对象的方法
// 方法1:对象拷贝继承
// for (var k in Person.prototype) {
// // 保留自己的 constructor 不要进行继承
// if (k === “constructor”) {
// continue;
// }
// Student.prototype[k] = Person.prototype[k];
// }
// 方法2:原型继承
Student.prototype = new Person();
Student.prototype.constructor = Student;
// 老师类型
function Teacher(name,age,sex,salary) {
Person.call(this,name,age,sex);
this.salary = salary;
}
// 创建学生的实例对象
var s1 = new Student(“zs”,18,“男”,89);
var s2 = new Student(“ls”,19,“男”,92);
console.dir(s1);
console.dir(s2);
s1.sayHi();
==============================================================
// 组合继承:属性在构造函数内部继承,方法通过原型继承
function Person(name,age) {
this.name = name;
this.age = age;
}
Person.prototype.sayHi = function () {
console.log(“你好”);
}
// 生成一个子类型
function Teacher(name,age,salary) {
// 继承父类的属性
Person.call(this,name,age);
this.salary = salary;
}
// 方法继承,通过原型对象继承
Teacher.prototype = new Person();
Teacher.prototype.constructor = Teacher;
// 生成老师的一个实例
var t1 = new Teacher(“wang”,45,10000);
console.dir(t1);
console.log(t1.name);
t1.sayHi();
====================================================================
-
两者的区别
-
函数声明必须有名字
-
函数声明会函数提升,在预解析阶段就已创建,声明前后都可以调用
-
函数表达式类似于变量赋值
-
函数表达式可以没有名字,例如匿名函数
-
函数表达式没有函数提升,在执行阶段创建,必须在表达式执行之后才可以调用
// 函数声明提升
// fun();
// fn();
// 函数声明
// 必须定义函数名
// function fun() {
// console.log(1);
// }
// 函数表达式
// 是将函数赋值给一个变量,可以是一个匿名函数
// var fn = function () {
// console.log(2);
// };
// fun();
// fn();
// 提前调用
// 现代浏览器进行的是变量声明提升
// fn();
// console.log(fn);
// 低版本浏览器可以进行函数声明提升
// 进行 if 语句中的函数提升
// if (true) {
// function fn() {
// console.log(“fn-true”);
// }
// } else {
// function fn() {
// console.log(“fn-false”);
// }
// }
var fn;
if (true) {
fn = function () {
console.log(“fn-true”);
}
} else {
fn = function () {
console.log(“fn-false”);
}
}
fn();
================================================================
- 函数本身也是对象,可以调用属性和方法
function fn(a,b) {
var a = 1;
console.log(a + b);
}
// 通过构造函数方法定义函数
// 函数本身也是一种对象
var fun = new Function(‘a’,‘b’,‘var a = “1”;console.log(a+b)’);
fun(2,3);
console.dir(fun);
====================================================================
- 普通的函数,是通过 给函数名或者变量名添加 () 方式执行,内部的 this 默认指向 window
function fun() {
console.log(this);
}
fun();
- 构造函数,是通过 new 关键字进行调用,内部的 this 指向的是将来创建的实例对象
function Person(name) {
this.name = name;
console.log(this);
}
var p1 = new Person(“zs”);
Person();
- 对象中的方法,是通过对象打点调用函数,然后加小括号,内部的 this 默认指向的是调用的对象自己
var o = {
sayHi: function () {
console.log(“haha”);
},
fn: fun
}
// this 的指向是要联系执行的上下文,在调用的时候,是按照什么方式调用,指向是不一样的
o.fn();
// o.sayHi();
- 事件函数,不需要加特殊的符号,只要事件被触发,会自动执行函数,事件函数的内部 this 指向的是事件源
document.onclick = function () {
console.log(“事件”);
};
- 定时器和延时器中的函数,不需要加特殊的符号,只要执行后,在规定的时间自动执行,默认内部的 this 指向的是 window
setInterval(function () {
console.log(“time”);
},1000);
| 调用方式 | 非严格模式 | 备注 |
| — | — | — |
| 普通函数调用 | window | 严格模式下是 undefined |
| 构造函数调用 | 实例对象 | 原型方法中 this 也是实例对象 |
| 对象方法调用 | 该方法所属对象 | 紧挨着的对象 |
| 事件绑定调用 | 绑定事件对象 | |
| 定时器函数 | window | |
===========================================================================
call
-
call() 方法调用一个函数,其具有一个指定的this值和分别地提供的参数(参数的列表)
-
注意:
-
该方法的作用和apply() 方法类似,只有一个区别,就是call() 方法接受的是若干个参数的列表,而apply() 方法接受的是一个包含多个参数的数组
-
语法:
-
fun.call(thisArg, arg1, arg2, arg3, …)
-
thisArg
-
在 fun 函数运行时指定的 this 值
-
如果指定了 null 或者 undefined 则内部 this 指向 window
-
arg1, arg2, …
-
指定的参数列表
function fun(a,b,c,d) {
console.log(this);
console.log(a + b + c + d);
}
// call 方法
// 1.功能:第一个可以指定函数的 this,第二个可以执行函数并传参
// 2.参数:第一个参数,传入一个指定让 this 指向的对象,第二个参数及以后,是函数参数的列表
// 3.返回值:就是函数自己的返回值
// 4.测试
var o = {
name: “zs”
}
fun.call(o,1,2);
apply
-
apply() 方法调用一个函数,第一个参数是一个指定的this值,第二个参数是以一个数组(或类似数组的对象)形式提供的参数
-
注意:
-
该方法的作用和call() 方法类似,只有一个区别,就是 call() 方法接受的是若干个参数的列表,而 apply() 方法接受的是一个包含多个参数的数组
-
语法:
-
fun.apply(thisArg, [argsArray])
function fun(a,b,c,d) {
console.log(this);
console.log(a + b + c + d);
}
var o = {
name: “zs”
}
// apply 方法
// 1.功能:第一个可以指定函数的 this,第二个可以执行函数并传参
// 2.参数:第一个参数,传入一个指定让 this 指向的对象,第二个参数是函数的参数组成的数组
// 3.返回值:就是函数自己的返回值
// 4.测试
fun.apply(o,[4,5]);
bind
-
bind() 函数会创建一个新函数(称为绑定函数)新函数与被调函数(绑定函数的目标函数)具有相同的函数体(在ECMAScript5规范中内置的call属性)
-
当目标函数被调用时 this 值绑定到bind()的第一个参数,该参数不能被重写。绑定函数被调用时,bind() 也接受预设的参数提供给原函数
-
一个绑定函数也能使用 new 操作符创建对象:这种行为就像把原函数当成构造器。提供的this 值被忽略,同时调用时的参数被提供给模拟函数。
-
语法:
-
fun.bind(thisArg, arg1, arg2, arg3, …)
function fun(a,b,c,d) {
console.log(this);
console.log(a + b + c + d);
}
var o = {
name: “zs”
}
// bind 方法
// 1.功能:第一个可以指定函数的 this,bind 方法不能执行函数,但是可以传参
// 2.参数:第一个参数,传入一个指定让 this 指向的对象,第二个参数及以后,是函数参数的列表
// 3.返回值:返回一个新的指定了 this 的函数,也可以叫绑定函数
// 4.测试
var fn = fun.bind(o,2,3);
console.log(fn);
fn(6,7);
==================================================================
// 构造函数扩展原型对象方法
// Array.prototype.getSum = function () {
// this 的指向
// };
// 数组中的方法
// var arr = [1,2,3,4];
// 使用的是 Array 构造函数的原型对象上的方法
// 方法内部的 this 指向的就是 arr 数组对象,操作的也是 arr 的对象
// arr.push();
// arr.splice();
// arr.getSum();
// {} 的对象自己是没有 push 方法的
// 类数组对象 getElementsByTagName
var o = {
0: 10,
1: 20,
2: 30,
length: 3
};
// console.log(o[0])
// 增加一项新的数据
// o[“3”] = 40;
// o.length = 4;
// 利用数组中的 push 方法,指定内部的this 为对象 o,就可以处理类数组对象的数据
Array.prototype.push.call(o,50);
console.log(o);
===================================================================
// apply 方法可以指定一个函数的 this,并且通过数组方式进行传参
// fun.apply(this,[1,2]);
// 定义一个数组,利用 apply 方法,可以将它拆开进行操作
var arr = [1,3,4,6,8];
// 想借用一些现在内置在js 中的方法
// console.log(Math.max(1,3,5,7,9));
// 利用 apply 方法,将数组传给 max 的第二个参数
// console.log(Math.max.apply(Math,arr));
console.log(1,2,3);
console.log.apply(console,arr);
==================================================================
// 想修改的是定时器的函数内部的 this
var o = {
name: “zs”,
age: 18,
s: function () {
setInterval(function () {
console.log(this.age);
}.bind(this),1000);
}
}
// o.s();
// 更改 事件函数中的 this
document.onclick = function () {
console.log(this);
}.bind(o);
=================================================================
- 自己打印输出一个函数
function fun() {
console.log(1);
}
console.dir(fun);
- 看一下函数内部的成员
function fn(a,b) {
最后
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
最后写上我自己一直喜欢的一句名言:
世界上只有一种真正的英雄主义就是在认清生活真相之后仍然热爱它