初级前端要掌握哪些知识点才能找到一个20k的工作?(二)
JavaScript
JavaScript基础
- 外部引入
js
文件:通过<script src="main.js"></script>
- 关键词
- 变量名大小写敏感
- 命名规范
JavaScript数据类型
- 字符串
(String)
- 数字
(Number)
- 布尔值
(Boolean)
- 未定义
(Undefined)
//undefined有两种结果
//1、真的没定义
alert(typeof dada); //undefined
//2、定义了,但是没有放东西进去
var dada;
alert(dada); //undefined
undefined
,表示未定义或只声明未给值的变量
- 对象
(Object)
js
中内置了如下的对象:
Object
是所有JS对象的超类(基类),JS中的所有对象都是继承自Object对象的Array
数组对象 定义数组属性和方法Number
数字对象Boolean
布尔对象 布尔值相关Error
错误对象 处理程序错误Function
函数对象 定义函数属性和方法Math
数学对象Date
日期对象RegExp
对象正则表达式对象 定义文本匹配与筛选规则String
字符串对象 定义字符串属性和方法
算术运算
var y = 3;
强制转换
- 字符串转数字
parseInt() parseFloat() isNaN()
- 数字转为字符串
toString()
赋值运算
- 复合的赋值运算符
+= -= *= /= %=
关系运算
- 关系运算:
> < <= >= != == === ==和=== !=和!==
“=”、“==”、“===”
有什么区别?
=
是赋值符号==
忽略数据类型的判断 是否相等===
数值和数据类型都要相等才判断为相等
逻辑运算
- 逻辑与
&&
- 逻辑或
||
- 逻辑非
!
- 复合逻辑表达式
三元运算
条件运算符?:
三元运算符:(比较表达式)?结果1:结果2
分支循环
程序运行的三大结构:顺序结构、选择结构、循环结构
- 单分支选择:
if
语句 - 双分支选择:
if-else
语句 - 多分支语句:
if-else if-else
语句
switch
语法格式
switch(num){ //表达式
case 1:
//执行代码块1
break; //中断执行,跳出
...
default: //默认,其他都不是的情况下执行
//执行代码块
break;
}
//强调:break非常重要,如果不加break的话,程序会一直继续往下执行;
while
语法格式:
while
循环的特点:不知道具体执行的次数时,使用最合适
while(条件表达式){
//要重复执行的代码段 - 循环体
}
do-while
语法格式:
do{
//循环体
}while(循环条件判断);
do-while
是先执行循环体,再检测循环条件。do-while
能保证循环体至少执行一次。- 其他循环无法保证循环至少执行一次。
for
for(1循环变量初始化;2循环条件判断;4循环变量的修改){
3循环体
}
break和continue
break
退出循环continue
跳过本次循环,继续下一次循环
数组
- 数组定义
var arr = new Array();
var arr = [];
- 字面量方式定义
var arr = ["1","2"];
- 向数组赋值
arr[0] = "1";
arr[1] = "2";
alert(arr[0]+","+arr[1]);
- 数组索引
arr[0]+","+arr[1]
- 数组长度
//语法
arr.length
//最后一个元素的索引
arr.length-1
数组方法
indexOf
数组可以通过indexOf()
来搜索一个指定的元素的位置,如未找到返回 -1
concat
concat()
方法把当前的 数组 和 另一个 数组连接起来,并返回一个新的 数组
var newArr = arr1.concat(arr2,"dada");
push和pop
push()
向数组的末尾添加若干元素,pop()
则把 数组的最后一个元素删除掉
arr.push("a","b");
console.log(arr);
arr.pop();
console.log(arr);
//空数组继续pop不会报错,而是返回undefined
unshift和shift
unshift()
向数组前面添加若干元素,shift()
则把数组的第一个元素删除掉
arr.unshift("a","b");
arr.shift();
slice
slice()
截取数组的部分元素,然后返回一个新的数组
console.log(arr.slice(0,3)); //从索引0开始,到索引3结束,但不包括3
console.log(arr.slice(3)); //从索引3开始到结束
如果不给
slice()
传递任何参数,就会从头到尾截取所有元素。利用这一点,可以很容易的复制一份新的数组
sort
sort()
可以对当前数组排序
var arr = ["b","c","a"];
arr.sort();
arr;//["a","b","c"]
reverse
reverse()
把整个数组的元素给掉个个
join
join()
方法把数组的每个元素用指定的字符串连接起来
var arr = ["a","b","c"];
arr.join("-"); //"a-b-c"
splice
可以从指定的索引开始删除若干元素,然后再从该位置添加若干元素
二维数组
var arr = [[1,2,3],["a","b","c"],"dadaqianduan"];
var x = arr[1][1]; //b
字符串
- 字符串属性
length
-字符串的长度属性 slice()
slice(start[,end]),start--开始索引 end--结束索引
substr()
substr(start[,length]),start:开始,取length个字符
split()
split([separator[,limit]])
,按条件分割字符串,返回数组
indexOf()
在父串中首次出现的位置,从0
开始!没有返回-1
lastIndexOf()
倒序查找
charAt(index)
charAt(index)
指定索引的字符
toLowerCase()
转小写
toUpperCase()
转大写
正则表达式
创建正则表达式
var reg = new RegExp("a","i");
// 将匹配字母a,第二个参数i,表示匹配时不分大小写
复制代码
元字符
模式修饰符
正则方法
test
方法
检索字符串中指定的值。
exec
方法
该方法用于检索字符串中的正则表达式的匹配,该函数返回一个数组,其中存放匹配的结果。如果未找到匹配,则返回值为 null
。
支持正则的 String方法
js对象
定义对象
//使用new运算符
var obj = new Object();
//字面量
var obj={
name:"dadaqianduan",
age:12,
sex:"男"
}
复制代码
对象的数据访问
//用.语法
obj.name
//用[]语法
obj["name"]
JSON
json(JavaScript Object Notation)
,是一种轻量级的数据交换格式。
var man = {
"name":"dadaqianduan",
"age":12,
"sex":"男"
};
内置对象
Object
是所有JS对象的超类(基类),JS中的所有对象都是继承自Object对象的Array
数组对象Number
数字对象Boolean
布尔对象Error
错误对象Function
函数对象Math
数学对象Date
日期对象RegExp
对象正则表达式对象String
字符串对象
Math 方法
abs()
绝对值 (去除正负)random()
随机数,0-1
之间的随机数,1
不会出现round()
四舍五入floor(x)
下舍入(向下取整)ceil(x)
上舍入(向上取整)max(x,y)
x 和 y
中的最大值min(x,y)
x 和 y
中的最小值cos(x)
x
的余弦sin(x)
x
的正弦sqrt(x)
返回x
的平方根pow(3,4)
返回3
的4
次方
Date 方法
getFullYear()
返回 年(4位)getMouth()
返回 月(0--11)getDate()
返回 日期getDay()
返回 星期 (0-6)getHours()
返回 小时getMinutes()
返回 分钟getSeconds()
返回秒getTime()
返回1970年1月1日午夜到指定日期(字符串)的毫秒数setFullYear()
设置 年份setMouth()
设置 月setDate()
设置 天setHours()
设置小时setMinutes()
设置 分钟setSeconds()
设置 秒setTime()
使用毫秒的形式设置时间对象
//判断闰年
function runYear(year){
if(year%4==0 && year%100!=0 || year%400==0){
return true;
}
};
面向对象是一种编程思想
- 类是一个抽象的概念
- 对象:具体的事物
- 类是对象的抽象,对象是类的具体实例
- 类不占用内存,对象占用内存空间
- 对象的访问 声明对象
- 遍历对象 –
for in
循环
定义对象
- 字面量创建
- 工厂模式
// 工厂模式中的函数,首字母大写
function Cat(n,c){
return {
name:n,
color:c,
say:function(){
alert("dadaqianduan")
}
}
}
- 构造函数
Javascript
提供了一个构造函数(Constructor)
模式。
所谓"构造函数",其实就是一个普通函数,但是内部使用了this
变量。
对构造函数使用new
运算符,就能生成实例,并且this
变量会绑定在实例对象上。
构造函数首字母大写
构造函数中的this
,指向的 实例化的对象
function Cat(n,c){
this.name=n;
this.color=c;
}
生成实例对象
var cat1 = new Cat("dadaqianduan","黄色")
// 自动含有一个constructor属性,指向它们的构造函数
实例:自动含有一个
constructor
属性,指向它们的构造函数
alert(cat1.constructor == Cat); //true
Javascript
还提供了一个instanceof
运算符
验证 原型对象 与 实例对象 之间的关系。
var txt = 'dadaqianduan';
alert(txt instanceof String); //false
var age = 123123;
alert(age instanceof Number); //false
var res = /\d/;
alert(res instanceof RegExp); //true
var arr = [];
alert(arr instanceof Array); //true
原型和原型链
构造函数都有一个
prototype
属性,指向 另一个对象 。这个对象的 所有属性和方法,都会被构造函数的实例继承。
所有的函数都是 Function
的实例。
在构造函数上都有一个 原型 属性prototype,prototype
也是一个对象;这个对象上有一个 constructor
属性,该属性指向的就是构造函数。
实例对象上有一个_proto_
属性,该属性也指向原型对象,该属性不是标准属性,不可以用在编程中,该属性用于浏览器内部使用。
constructor
constructor
是构造函数 创建的实例的属性,该属性的作用是 指向 创建当前对象的 构造函数。
son.constructor == parent; // true
每个原型都有一个constructor
属性,指向该关联的构造函数。
function Person() {
}
console.log(Person===Person.prototype.constructor) //true
关系图:
区分一下普通对象和函数对象
function f1(){};
var f2 = function(){};
var f3 = new function(){};
var o1 = {};
var o2 = new Object();
var o3 = new f1();
console.log(typeof Object); //function
console.log(typeof Function);//function
console.log(typeof f1) //function
console.log(typeof f2) // function
console.log(typeof f3) //function
console.log(typeof o1) //object
console.log(typeof o2) //object
console.log(typeof o3)// object
- 在
JavaScript
中,原型是一个对象,原型的作用是 实现对象的继承。 - 在
JavaScript
中的所有函数对象中,都存在一个属性,prototype
,该属性对应当前对象的原型。 - 所有的
JavaScript
对象,都存在一个_proto_
属性,_proto_
属性指向实例对象的构造函数的原型。
var p = new Person(); // 实例对象
console.log(p._proto_ === Person.prototype); // true
p
是实例对象,Person
是p
的构造函数。p
的_proto_
属性 指向 构造函数Person
的原型。
js
是如何通过原型进行继承的:
var parent = function(name) {
this.name = name;
}
parent.prototype.getName = function() {
return this.name;
}
var son = new parent("dadaqianduan");
console.log(son.getName()); // dadaqianduan
son
继承了parent
的原型中的函数属性getName
原型链
除了
Object
的prototype
的原型是null
外,所有的对象 和 原型 都有自己的原型,对象的原型 指向 原型对象。
在层级多的关系中,多个原型层层相连 则 构成了 原型链。
在查找一个对象的属性时,如当前对象找不到该属性,就会沿着原型链一直往上查找,直到找到为止,如果到了原型链顶端,没找到,则返回undefined
原型
- 所有引用类型都有一个
__proto__
属性 - 所有函数都有一个
prototype
属性 - 所有引用类型的
__proto__
属性指向它构造函数的prototype
构造函数和实例原型之间的关系:
Person
(构造函数) 的 prototype
指向 Person.prototype
__proto__
每个对象,除null
外,都有的属性叫__proto__
,这个属性会指向该对象的原型。
function Person() {
}
var person = new Person();
console.log(person.__proto__ === Person.prototype); // true
关系图:
关系图:
关系图:
梳理:
写一个构造函数Person
,一般构造函数区别与普通函数要求首字母大写:
function Person(){}
prototype
原型
原型 是 一个对象,在原型prototype
上定义的属性,通过“继承”,实现 实例 也有这个属性。
继承 是在 new
操作符内部实现的。
构造函数 内部 有个
prototype
的属性,通过这个属性就能访问到 原型。
Person
是构造函数,Person.prototype
是原型。
- 实例
有构造函数,可以在原型上创建可继承的属性,通过new
操作符创建实例:
function Person(){}
person = new Person()
da = person instanceof Person // 检查person是否是Person的实例
da // true
// 继承
function Person() {}
Person.prototype.name = 'dadaqianduan.cn'
person = new Person()
da = person.name // 实例继承的属性
da // 'dadaqianduan.cn'
proto
实例通过_proto_
访问到原型。
function Person() {}
Person.prototype.name = 'dadaqianduan.cn'
person = new Person()
da = person.__proto__ === Person.prototype
da // true
constructor
构造函数
原型也可以通过
constructor
访问到构造函数
function Person() {}
Person.prototype.name = 'dadaqianduan.cn'
person = new Person
da = Person.prototype.constructor === Person
da // true
小结
- 所有引用类型(函数,数组,对象)都拥有
__proto__
属性。 - 所有函数拥有
prototype
属性。 - 每个实例对象(
Object
)都有一个私有属性,为__proto__
指向它的构造函数的原型对象(prototype
)。该原型对象也有一个自己的原型对象__proto__
,层层向上直到一个对象的原型对象为null
,null
没有原型,并作为这个原型链中的最后一个环节。
常用的JavaScript设计模式
百度百科:
设计模式(Design pattern)
是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。
使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的;设计模式使代码编制真正工程化;设计模式是软件工程的基石脉络,如同大厦的结构一样。
单体模式
单体是一个用来划分 命名空间并将一批相关的属性和方法组织在一起的对象,如果它可以被实例化,那么它只能被实例化一次。
特点:
(1)可以来划分命名空间,从而清除全局变量所带来的危险。
(2)利用分支技术来来封装浏览器之间的差异。
(3)可以把代码组织的更为一体,便于阅读和维护。
工厂模式
工厂模式的定义:
提供创建对象的接口,意思就是根据领导(调用者)的指示(参数),生产相应的产品(对象)。
- 创建一个对象常常需要复杂的过程,所以不适合在一个复杂的对象中。
- 创建对象可能会导致大量的重复代码,也可能提供不了足够级别的抽象。
工厂就是把成员对象的创建工作转交给一个外部对象,好处在于消除对象之间的耦合(也就是相互影响)。
分类:
简单工厂模式:使用一个类,通常为单体,来生成实例。
复杂工厂模式定义:将其成员对象的实列化推到子类中,子类可以重写父类接口方法以便创建的时候指定自己的对象类型。
父类只对创建过程中的一般性问题进行处理,这些处理会被子类继承,子类之间是相互独立的,具体的业务逻辑会放在子类中进行编写。
应用场景:
以下几种情景下工厂模式特别有用:
(1)对象的构建十分复杂;
(2)需要依赖具体环境创建不同实例;
(3)处理大量具有相同属性的小对象。
单例模式
单例模式定义了一个对象的创建过程,此对象只有一个单独的实例,并提供一个访问它的全局访问点。也可以说单例就是保证一个类只有一个实例,实现的方法一般是先判断实例存在与否,如果存在直接返回,如果不存在就创建了再返回,这就确保了一个类只有一个实例对象。
使用闭包方式来实现单例:
var single = (function(){
var unique;
function getInstance(){
// 如果该实例存在,则直接返回,否则就对其实例化
if( unique === undefined ){
unique = new Construct();
}
return unique;
}
function Construct(){
// ... 生成单例的构造函数的代码
}
return {
getInstance : getInstance
}
})();
unique
是返回对象的引用,而getInstance
是静态方法获得实例。Construct
是创建实例的构造函数。
可以通过 single.getInstance()
来获取到单例,并且每次调用均获取到同一个单例。这就是 单例模式 所实现的效果。
应用场景:
- 单例模式是一种常用的模式,有一些对象我们往往只需要一个,比如全局缓存、浏览器的
window
对象。 - 借助单例模式,可以把代码组织的更为一致,方便阅读与维护。
本文连载中,敬请期待哦~
下面要分享的前端面试题是我面试过程中遇到的题目,每一次面试后我都会复盘总结。我做了一个整理,并且在技术博客找到了专业的解答,分了HTML、css、JavaScript、React、Vue、浏览器、服务端与网络、算法等等.....大家可以参考下: