1、canvas和svg的区别
canvas
- 基于像素
- 单个html,类似画笔在画布上画画
svg
- 基于对象模型
- 多个图形元素
- 高保真(不失真,不变形)
2、vdom
- 用 js 来模拟 DOM 结构
- dom 变化的对比,放在js层来执行
- 提高重绘性能
- DOM操作比较占内存,将dom操作放在js层,可以提高效率性能
3、数组的方法
- push(),会返回改变后数组的长度
- concat
- shift
- unshift
- splice
4、jsonp
- jsonp是一个简单高效的跨域方式,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问。
- 特点:不受同源策略的限制,兼容性更好,易于实现,只支持get。
5、IE盒子模型和谷歌的区别
- W3C的盒模型方式被称为“
content-box
” - IE的被称为“
border-box
” -
box-sizing: border-box;
就是为了在设置有padding值和border值的时候不把宽度撑开。
6、js原型、原型链
-
.prototype
只是一个指针,指向的是原型对象 -
对象的prototype.constructor就是对象本身
Object.prototype.constructor==Object
-
原型链指原型与原型层层相连接的过程即为原型链,访问一个对象的属性,这对象内部不存在这个属性就会去它的原型对象中找,一直找下去,就是原型链的概念。
-
原型链的尽头一般都是
Object.prototype
Object.prototype.__proto__
为null
7、跨域问题
-
jsonp跨域
JSONP(JSON with Padding:填充式JSON),应用JSON的一种新方法, -
JSON、JSONP的区别:
1、JSON返回的是一串数据、JSONP返回的是脚本代码(包含一个函数调用)
2、JSONP 只支持get请求、不支持post请求
(类似往页面添加一个script标签,通过src属性去触发对指定地址的请求,故只能是Get请求) -
nginx反向代理:
-
服务端端修改header
header(‘Access-Control-Allow-Origin:*’);//允许所有来源访问
header(‘Access-Control-Allow-Method:POST,GET’);//允许访问的方式
8、es6新数据类型symbol
- symbol是es6新推出的一种基本数据类型,表示独一无二的值。最大用途就是用来定义对象唯一的属性名
9、ajax实现
创建XMLHttpRequest对象。
设置请求方式。
调用回调函数。
发送请求。
//第一步:创建XMLHttpRequest对象
var xmlHttp;
if (window.XMLHttpRequest) { //非IE
xmlHttp = new XMLHttpRequest();
} else if (window.ActiveXObject) { //IE
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP")
}
//第二步:设置和服务器端交互的相应参数,向路径http://localhost:8080/getAjax准备发送数据
var url = "http://localhost:8080/getAjax";
xmlHttp.open("POST", url, true);
// open(method,url,async) post/get
// .send(string) 仅用于post
//第三步:注册回调函数
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState == 4) {
if (xmlHttp.status == 200) {
var obj = document.getElementById(id);
obj.innerHTML = xmlHttp.responseText;
} else {
alert("AJAX服务器返回错误!");
}
}
}
//第四步:设置发送请求的内容和发送报送。然后发送请求
var params = "userName=" + document.getElementsByName("userName")[0].value + "&userPass=" + document.getElementsByName("userPass")[0].value + "&time=" + Math.random(); // 增加time随机参数,防止读取缓存
xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded;charset=UTF-8"); // 向请求添加 HTTP 头,POST如果有数据一定加加!!!!
xmlHttp.send(params);
10、react render之后发生了什么
- 1、React创建元素,解析组件标签,找到MyComponent 组件
- 2、发现组件是使用类定义的,随后new出来该类的实例,并通过该实例调用到原型上的render方法
- 3、将render返回的虚拟DOM转为真实DOM,随后呈现在页面中。
10.1、react高阶组件
- 定义:高阶组件(Higher Order Component,HOC)并不是React提供的某种API,而是使用React的一种模式,一个高阶组件就是一个函数,这个函数接受一个组件作为输入,然后返回一个新的组件作为结果
- 意义:1、重用代码。2、修改现有react组件的行为
- 实现方式:
1、代理方式的高阶组件
2、继承方式的高阶组件
11、this.setState可以放在constructor中吗
- 直接放在constructor中不会报错,但是也不会生效
- 原因:this.setState( )本身是异步的,类似于是一种请求而不是立即更新组件的命令,为了更好的性能,React会延迟调用它,不会保证state的变更会立即生效,而是会批量推迟更新
constructor(props){
super(props)
this.state = {
name:'qss'
}
this.setState({
name:'qss3'
})
}
- 配合settimeout会生效,官方建议放在componentDidUpdate中执行或利用回调函数(setState(updater, callback))
constructor(props){
super(props)
this.state = {
name:'qss'
}
setTimeout(()=>{
this.setState({
name:'qss3'
})
},1000)
}
12、call、apply、bind
- 作用:改变this的指向
- 第一个参数都是this的指向
- call/apply直接返回结果,bind返回的是一个函数
- call/bind,第一个参数是this,后面跟参数列表。apply两个参数,第二个参数接收一个数组
13、redux
- 如果UI层非常简单,没有很多互动,Redux 就是不必要的,用了反而增加复杂性。
- redux取值,在需要使用store中的状态值得组件导出的时候,使用connect
例如:export default connect(组件名)
,组件中可直接使用,this.props.状态名
来使用 - 链接https://blog.csdn.net/sinat_41904410/article/details/102961499
14、vue和react的区别
-
vue 提供了一系列的api, 而react的api 很少
-
vue的思想是响应式的,也就是基于是数据可变的,实现了数据的双向绑定,react整体是函数式的思想,是单向数据流,推崇结合immutable来实现数据不可变
-
vue 采用了template, react采用了jsx (本质上都是模版)
-
React依赖Virtual DOM,而Vue.js使用的是DOM模板。React采用的Virtual DOM会对渲染出来的结果做脏检查。
-
Vue.js在模板中提供了指令,过滤器等,可以非常方便,快捷地操作DOM。
15、vuex的相关属性、vuex的模块化
state, getters, mutations, actions, modules。
1. state:vuex的基本数据,用来存储变量
2. geeter:从基本数据(state)派生的数据,相当于state的计算属性
3. mutation:提交更新数据的方法,必须是同步的(如果需要异步使用action)。每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。
回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数,提交载荷作为第二个参数。
4. action:和mutation的功能大致相同,不同之处在于 ==》1. Action 提交的是 mutation,而不是直接变更状态。 2. Action 可以包含任意异步操作。
5. modules:模块化vuex,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理。
16、vue父子组件传值,兄弟组件之间的传值
- 父传子,属性形式传递,props接收
- 子传父,函数形式,使用$emit() 调用父级函数传递
- 兄弟组件之间传值,也是通过$emit;
原理是:vue一个新的实例,类似于一个站,连接着两个组件,也就是一个*事件总线;eventBus
17、webpack/gulp
- webpack核心代码
- Webpack有人也称之为 模块打包机
- Webpack更侧重于模块打包,当然我们可以把开发中的所有资源(图片、js文件、css文件等)都可以看成模块,最初Webpack本身就是为前端JS代码打包而设计的,后来被扩展到其他资源的打包处理。Webpack是通过loader(加载器)和plugins(插件)对资源进行处理的。
const path = require('path');
var webpack = require("webpack");
const config = {
entry: {
main: './src/index.js'
},
output: {
filename: '[name]-[hash:8].js',
path: path.join(__dirname, 'dist'),
},
module: {
rules: [
{
test: /\.html/, use: ['html-loader']
}
]
},
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
template: __dirname + '/index.html'
})
]
}
module.exports = config;
- gulp核心代码
- Gulp侧重于前端开发的 整个过程 的控制管理(像是流水线)
- 通过给gulp配置不通的task(通过Gulp中的gulp.task()方法配置,比如启动server、sass/less预编译、文件的合并压缩等等)来让gulp实现不同的功能,从而构建整个前端开发流程。
var gulp = require('gulp');
var sass = require('gulp-sass');
gulp.task('hello', function() {
// 将你的默认的任务代码放在这
console.log('hello world!');
});
gulp.task('sass',function(){
return gulp.src('src/main/webapp/static/styles/scss/apply.scss')
.pipe(sass())
.pipe(gulp.dest('src/main/webapp/static/styles/css'))
});
17webpack loader和plugins
1、loader:
- loader从字面的意思理解,是 加载 的意思。
- loader是运行在NodeJS中。
- 由于webpack 本身只能打包commonjs规范的js文件,所以,针对css,图片等格式的文件没法打包,就需要引入第三方的模块进行打包。css-loader和style-loader模块等等
- loader运行在打包文件之前(loader为在模块加载时的预处理文件)
2、plugin
- 也是为了扩展webpack的功能
- plugin 是作用于webpack本身上的。
- 针对html文件打包和拷贝(还有很多设置)的插件:html-webpack-plugin。
- plugins在整个编译周期都起作用。
18、闭包
- 闭包就是可以访问函数内部参数的函数
- 优点是:避免全局变量污染,变量一直存在在内存中
- 缺点是:变量一直存在在内存中,如果使用不当会导致内存泄漏,需要在退出函数时将不用的参数删除
19、vue中template里面的和render里面的区别是啥
-
相同之处:
render 函数 跟 template 一样都是创建 html 模板 -
不同之处:
1、Template适合逻辑简单,render适合复杂逻辑。
2、使用者template理解起来相对容易,但灵活性不足;自定义render函数灵活性高,但对使用者要求较高。
3、render的性能较高,template性能较低。这一点我们可以看一下,下图中vue组件渲染的流程图可知。
4、基于上一点,我们通过vue组件渲染流程图知道,使用render函数渲染没有编译过程,相当于使用者直接将代码给程序。所以,使用它对使用者要求高,且易出现错误
5、Render 函数的优先级要比template的级别要高,但是要注意的是Mustache(双花括号)语法就不能再次使用
20、vue双向绑定的原理
- 通过
object.defineproperty()
来劫持各个属性的setter/getter
,在数据变动时,发布消息给订阅者,触发相应的监听回调
21、keep-alive 触发的生命周期
-
当引入keep-alive的时候,页面第一次进入,钩子的触发顺序
created-> mounted-> activated
,退出时触发deactivated
。当再次进入(前进或者后退)时,只触发activated
。 -
事件挂载的方法等,只执行一次的放在
mounted
中;组件每次进去执行的方法放在activated
中;
22、computed/watch、computed可以监听单个属性吗,待试试?
- computed 监听多个属性,影响一个值,例如购物车结算
- watch 监听单个属性,一条数据影响多条数据,例如数据搜索
23、require 和 import 区别
- 模块加载时间:require运行时动态加载、import在编译时静态加载(效率更高,需要放在顶部)
- 使用位置:require可以在函数、判断语句等代码块中加载,import必须在顶部加载
- 等等
24、new 一个函数相关
1.新创建一个空对象
var fn = new Object();
2.构造函数的显示原型等于实例对象的隐式原型,实例对象的constructor属性为构造函数的名称
Fn.prototype = fn.__proto__
3.通过调用call、apply方法执行构造函数并改变this对象(绑定到实例对象上)
Fn.call(f)
function myNew (fun) {
return function () {
// 创建一个新对象且将其隐式原型指向构造函数原型
let obj = {
__proto__ : fun.prototype
}
// 执行构造函数
fun.call(obj, ...arguments)
// 返回该对象
return obj
}
}
function person(name, age) {
this.name = name
this.age = age
}
let obj = myNew(person)('li', 18)
4.如果没有手动返回其他任何对象或返回值是基本类型(Number、String、Boolean)的值,会返回 this 指向的新对象,也就是实例,若返回值是引用类型(Object、Array、Function)的值,则实际返回值为这个引用类型。
25、深拷贝,浅拷贝区别,
- 浅拷贝是复制原对象,共享一个内存,修改的话会影响原对象的值
- 深拷贝会创建一个一模一样的对象,不共享内存,修改互不影响
- 深拷贝函数的思路:
1、判断目标是对象还是数组,初始赋值{} || []
2、for in 遍历目标
3、hasOwnProperty() 判断当前值是否存在
4、判断是否是对象,否,直接赋值,是,判断当前对象是对象还是数组,再次调用拷贝函数
26、JSON.parse(JSON.stringfy)有啥弊端
- obj里的时间对象new Date()会被改为字符串形式,而不再是时间对象
- obj里有RegExp、Error对象,会得到空对象
- obj里有函数,undefined、symbol 会丢失
- obj里有NaN、Infinity和-Infinity,会变为null
- JSON.stringify()只能序列化对象的可枚举的自有属性,例如 如果obj中的对象是有构造函数生成的, 则使用JSON.parse(JSON.stringify(obj))深拷贝后,会丢弃对象的constructor;