表现
紧张,应该吧,好像是,可能也许大概= =
自信点!-> 是这样!就是这样!
其实主要是准备不充分...
题目
网络安全
什么是XSS、CSRF
- XSS:跨站脚本(Cross-site scripting,通常简称为XSS)
通过客户端脚本语言(如:JavaScript)在一个论坛发帖中发布一段恶意的
JavaScript代码就是脚本注入
,如果这个代码内容有请求外部服务器
,那么就叫做XSS!
比如用js写一个跨站脚本,携带用户的cookie发送给某个服务器,这个服务器可以利用用户的隐私信息,做其他一些恶意的业务处理(获取用户隐私存入自身数据库等)。注意此时并没有发生CSRF,因为没有冒充用户向其他服务器发起请求,只是将数据存储起来了。
- CSRF:跨站请求伪造(英语:Cross-site request forgery)
又称XSRF,
冒充用户发起请求
(在用户不知情的情况下),完成一些违背用户意愿的请求(如恶意发帖,删帖,改密码,发邮件等)。
比如在用户不知情的情况下让他们触发点击某个请求链接,完成非用户本意的一些向其他服务器的请求。注意此时并没有用到XSS,因为没有脚本注入。
微信小程序
小程序工作流程
微信小程序的框架包含两部分View视图层
(可能存在多个)、App Service逻辑层
(一个),View层用来渲染页面结构,AppService层用来逻辑处理、数据请求、接口调用,它们在两个线程里运行。
视图层使用WebView
渲染,逻辑层使用JSCore
运行。
视图层和逻辑层通过系统层的WeixinJsBridage
进行通信,逻辑层把数据变化通知到视图层,触发视图层页面更新,视图层把触发的事件通知到逻辑层进行业务处理。
双线程模型将逻辑层与视图层进行分离,它们之间只有数据的通信,可以防止开发者随意操作界面,更好地保证用户的数据安全
。
页面渲染具体流程:在渲染层,宿主环境会把WXML转换成对应的js对象,在逻辑层发生数据变更的时候,我们需要通过宿主环境提供的setData方法把数据从逻辑层传递到渲染层,再经过对比前后差异,把差异应用在原来的DOM树上,渲染出正确的ui界面。
ES6
Async await的原理是什么?ES5是如何实现的?
解决函数回调经历了几个阶段, Promise 对象, Generator 函数到async函数。async函数目前是解决函数回调的最佳方案。
- 用法 async 函数返回一个 Promise 对象,当函数执行的时候,一旦遇到 await 就会先返回,等到触发的异步操作完成,再接着执行函数体内后面的语句。
function getNum(num){
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(num+1)
}, 1000)
})
}
// 在function外部书写async,在内部需要等待执行的函数前书写await
const func = async ()=>{
const f1 = await getNum(1)
const f2 = await getNum(f1)
console.log(f2)
// 输出3
}
func()
- 原理 async/await实际上是对Generator(生成器)的封装,是一个语法糖。
但二者又有三点不同:
- async/await自带执行器,不需要手动调用next()就能自动执行下一步
- async函数返回值是Promise对象,而Generator返回的是生成器对象
- await能够返回Promise的resolve/reject的值 我们对async/await的实现,其实就是对应以上三点封装Generator。
// 定义了一个promise,用来模拟异步请求,作用是传入参数++
function getNum(num){
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(num+1)
}, 1000)
})
}
//自动执行器,如果一个Generator函数没有执行完,则递归调用
function asyncFun(func){
var gen = func();
function next(data){
var result = gen.next(data);
if (result.done) return result.value;
result.value.then(function(data){
next(data);
});
}
// 自动执行
next();
}
// 所需要执行的Generator函数,内部的数据在执行完成一步的promise之后,再调用下一步
var func = function* (){
var f1 = yield getNum(1);
var f2 = yield getNum(f1);
console.log(f2) ;
};
asyncFun(func);
- ES5实现
// 通过 babel 转码之后的 ES5 代码
function _asyncToGenerator(fn) {
return function() {
var gen = fn.apply(this, arguments)
// 返回promise
return new Promise(function(resolve, reject) {
function step(key, arg) {
try {
// 调用next执行结果
var info = gen[key](arg)
// 执行结果的value值
var value = info.value
} catch (error) {
reject(error)
return
}
// 全部执行完毕,执行resolve
if (info.done) {
resolve(value)
} else {
// 还没有执行完,返回promise
return Promise.resolve(value).then(
function(value) {
step('next', value)
},
function(err) {
step('throw', err)
}
)
}
}
// 返回时自动执行
return step('next')
})
}
}
Typescript
typescript中type 和 interface的区别?
因为在 Typescript 里 type 和 interface 都能实现类型的定义,因此在一些使用方面他们都很像,都是可以描述一个对象或函数。
- 使用上
// 使用 type 定义了一个符合类型的别名
type TUserListResult = Promise<{
total: number,
list: [{
title: string,
id: number,
}],
}>
// 使用 interface 定义了一个复合类型接口
interface IDataListResult {
total: number,
list: [{
title: string,
id: number,
}],
}
function (offset: number): TUserListResult {
return new Promise((resolve, reject) => {
});
}
function getDataList(offset: number): Promise<IDataListResult> {
return new Promise((resolve, reject) => {
});
}
- 实现继承的表现形式不同
// 与类的继承相似
interface Name {
name: string;
}
interface User extends Name {
age: number;
}
// type 利用交叉类型实现的继承
type Name = {
name: string;
}
type User = Name & { age: number };
- 声明上
type 作为类型的别名,可以轻易的实现声明基本类型别名,联合类型,元组等类型,而 interface 则不行。
此除之外,type 还能通过 typeof 获取类型,并声明。
let div = document.createElement('div');
type B = typeof div;
interface 能够声明合并,而 type 不行(会报重复声明错误)。
interface User {
name: string,
age: number,
}
interface User {
sex: string,
}
在通常情况下,都是使用 interface 定义类型,在极少情况下会使用 type。
泛型是什么?有什么应用场景
- 泛型是什么 泛型的本质是参数化类型,通俗的将就是所操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和方法的创建中,分别成为泛型类,泛型接口、泛型方法。
TypeScript 中不建议使用 any 类型,不能保证类型安全,调试时缺乏完整的信息。
- 应用场景 TypeScript可以使用泛型来创建可重用的组件。支持当前数据类型,同时也能支持未来的数据类型。扩展灵活。可以在编译时发现你的类型错误,从而保证了类型安全。
我们还可以在接口中使用泛型。
后端提供了一些接口,用以返回一些数据,依据返回的数据格式定义如下接口:
interface IResponseData {
code: number;
message?: string;
data: any;
}
根据接口,我们封装对应的一些方法。
function getData(url: string) {
return fetch(url).then(res => {
return res.json();
}).then( (data: IResponseData) => {
return data;
});
}
但是,该接口的 data 项的具体格式不确定,不同的接口会返回的数据是不一样的,当我们想根据具体当前请求的接口返回具体 data 格式的时候,就比较麻烦了,因为 getData 并不清楚你调用的具体接口是什么,对应的数据又会是什么样的。这个时候我们可以对 IResponseData 使用泛型.
interface IResponseData<T> {
code: number;
message?: string;
data: T;
}
function getData<U>(url: string) {
return fetch(url).then(res => {
return res.json();
}).then( (data: IResponseData<U>) => {
return data;
});
}