J.L's BLOG

划船不用浆,一生全靠浪


  • 首页

  • 标签

  • 归档

interface

发表于 2019-05-29 |
字数统计: 187 | 阅读时长 ≈ 1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

interface IPerson {
name: string;
age: number

}

class Person {
//接口的第一个用法 ,作为一个方法的参数的类型声明(声明属性)
constructor(public config: IPerson) {

}
}

//传入的对象必须符合接口的定义,(名称一样,数量一样)
var p1 = new Person({
name: '3',
age:4
})



//接口的第二个用法 ,(声明一个方法)
interface Animal{
eat()
}

//Sheep类去实现Animal这个接口
//当一个类要去实现一个一个接口的时候,必须要实现接口里边声明的方法
class Sheep implements Animal{
eat() {
console.log('============== i am eat grass',);
}
}

class Tiger implements Animal{
eat() {
console.log('============== i am eat meat',);
}
}

for

发表于 2019-05-29 |
字数统计: 210 | 阅读时长 ≈ 1

forEach

1
2
3
4
5
6
7
8

var arr = [1,2,3,4]
arr.desc = "an array"

arr.forEach(val => {
console.log('==============',val)
// 1,2,3,4
})

注意的点

  • 循环不能被中断(for 循环可以)
  • 属性会被忽略掉
  • 循环得到的第一个参数是value,第二个参数是key

forin

1
2
3
4
5
6
7
8
9

var arr = [1,2,3,4]
arr.desc = "an array"


for (var key in arr){
console.log('==============',key)
// 0,1,2,3,desc
}

注意的点

  • 循环可以被中断(for 循环可以)
  • 属性会被循环出来
  • 循环得到的是key

forof(与forEach类似,区别在于forof可以break)

1
2
3
4
5
6
7
8
9

var arr = [1,2,3,4]
arr.desc = "an array"


for (var val of arr){
console.log('==============',val)
// 1,2,3,4
}

注意的点

  • 循环可以被中断(for 循环可以)
  • 属性不会被循环出来
  • 循环得到的是value

class类.md

发表于 2019-05-29 |
字数统计: 271 | 阅读时长 ≈ 1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
class Persion{

//只有在类被实例化的时候才会被调用(每一次实例化只会调用一次)
//只能在类的内部被访问到
constructor(public name: string){
console.log('==============father','constructor');
}

//默认是public,类的内外都可以访问
// public name;

//类的内部和子类的才可以访问
protected age;

//类的内部才可访问的到
private sex;

eat(){
console.log('==============eating');
}
}

//extends关键字是用来声明一种继承关系
//子类会继承父类的所有属性和方法
class Employee extends Persion {

constructor(name: string, code: string) {
//super的第一个作用,调用父类的构造函数
super(name)
this.code = code
console.log('==============son','constructor');
}
code: string;

work() {
//super的第二个作用,调用父类的其他方法
super.eat()
this.doWork()
}

doWork(){
console.log('==============doWork',);
}
}

let el = new Employee('name', '111')
el.work()



let p1 =new Persion('liu')
p1.name = "batMan"
//p1.eat()

let p2 =new Persion('jia')
p2.name = "superMan"
//p2.eat()

原型及原型链

发表于 2019-03-19 |
字数统计: 1,023 | 阅读时长 ≈ 4

原型概述

当谈到继承时,JavaScript 只有一种结构:对象。每个实例对象(object )都有一个私有属性(称之为proto)指向它的原型对象(prototype)。该原型对象也有一个自己的原型对象(proto) ,层层向上直到一个对象的原型对象为 null。根据定义,null 没有原型,并作为这个原型链中的最后一个环节。

几乎所有 JavaScript 中的对象都是位于原型链顶端的Object的实例。

1
2
3
4
5
6
7
var a = {}
var b= new Object()

a.__proto__ === b.__proto__ //true 一般情况 obj.constructor.prototype === obj.__proto__

//等同于下方
a.constructor === b.constructor === Object() //true
阅读全文 »

性能优化

发表于 2019-03-19 |
字数统计: 626 | 阅读时长 ≈ 2

性能优化

网络请求优化

DNS Lookup,减少重定向,避免 JS、CSS 阻塞,并行请求,代码压缩,缓存,按需加载,前端模块化

前端渲染的优化

在改变文档根元素的字体颜色等视觉性信息时,会触发整个文档的重绘,而改变某元素的字体颜色则只触发特定元素的重绘;改变元素的位置信息会同时触发此元素(可能还包括其兄弟元素或子级元素)的布局和重绘。某些重大改变,如更改文档根元素的字体尺寸,则会触发整个文档的重新布局和重绘,据此及上文所述,推荐以下优化和实践:

  • HTML文档结构层次尽量少,最好不深于六层;
  • 脚本尽量后放,放在前即可;
  • 少量首屏样式内联放在标签内;
  • 样式结构层次尽量简单;
  • 在脚本中尽量减少DOM操作,尽量缓存访问DOM的样式信息,避免过度触发回流;
  • 减少通过JavaScript代码修改元素样式,尽量使用修改class名方式操作样式或动画;
  • 动画尽量使用在绝对定位或固定定位的元素上;
  • 隐藏在屏幕外,或在页面滚动时,尽量停止动画;
  • 尽量缓存DOM查找,查找器尽量简洁;
  • 涉及多域名的网站,可以开启域名预解析
阅读全文 »

new的作用

发表于 2019-03-16 |
字数统计: 700 | 阅读时长 ≈ 3

new 的作用

1
2
3
4
5
6
7
8
9
10
11
function Test(name){
this.name = name
}

Test.prototype.sayName = function (){
console.log('xxxxx',this.name)
}

const t = new Test('Jeffrey')
console.log(t.name) // 'Jeffrey'
t.sayName() // 'Jeffrey'

从代码中我们可以知道,new的作用

  • 通过构造函数Test创建出来的实例可以访问到构造函数中的属性
  • 通过构造函数Test创建出来的实例可以访问到构造函数原型链中的属性,也就是说通过new操作符实例与构造函数通过原型链连接了起来
阅读全文 »

JS空值

发表于 2019-03-16 |
字数统计: 308 | 阅读时长 ≈ 1

null,undefined

  • null是一个表示”无”的对象,转为数值时为0
  • undefined是一个表示”无”的原始值,转为数值时为NaN
1
2
3
4
5
Number(null) //0
//null+5=0

Number(undefined) //NAN
//undefined+5=NAN
  • null 表示一个值被定义了,定义为“空值”;
  • undefined 表示根本不存在定义。
  • 所以设置一个值为 null 是合理的,如objA.valueA = null;但设置一个值为 undefined 是不合理的

  • null针对的是对象,表示一个未分配内存指针的对象,undefined针对原始类型,就是变量存放值的那个盒子里是空的

阅读全文 »

居中案例

发表于 2018-12-15 | 分类于 前端 |
字数统计: 425 | 阅读时长 ≈ 2

1.水平居中

1.1行内元素

  • text-align:center

1.2块级元素

  • margin:0 auto
阅读全文 »

跨域

发表于 2018-12-03 |
字数统计: 793 | 阅读时长 ≈ 4

跨域

1、JSONP实现

优缺点

  • 优点: 无兼容性问题
  • 缺点: 只能发送get请求(如果要实现post,参考下边文章)

    [‘https://segmentfault.com/a/1190000015597029#articleHeader5']

JSONP实现方式

它的基本思想是,网页通过添加一个<script>元素,向服务器请求JSON数据,这种做法不受同源政策限制;服务器收到请求后,将数据放在一个指定名字的回调函数里传回来。

首先,网页动态插入<script>元素,由它向跨源网址发出请求。(客户端代码)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
</body>

<script>
function addScriptTag(src) {
var script = document.createElement('script');
script.setAttribute("type","text/javascript");
script.src = src;
document.body.appendChild(script);
}

window.onload = function () {
// addScriptTag('http://example.com/ip?callback=foo');
addScriptTag('http://localhost:3000/user?callback=foo');
}

function foo(data) {
console.log('xxxxx',data)
}
</script>
<!--<script src="http://localhost:3000/user?callback=foo"></script>-->

</html>

上面代码通过动态添加<script>元素,向服务器localhost:3000发出请求。注意,该请求的查询字符串有一个callback参数,用来指定回调函数的名字,这对于JSONP是必需的。

服务器端代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const http = require('http')
const url = require('url')
http.createServer((req, res) => {
const data = {name: 'uthus'}
// 获取查询参数callback,就是我们在客户端定义的jsonpCb
const callback = url.parse(req.url, true).query.callback
if (callback) {
const str = callback + '(' + JSON.stringify(data) + ')'
// 以字符串的形式返回
res.end(str)
} else {
res.end('hello world')
}
}).listen(3000)
console.log('xxxxxxxxxxx000', 'listen at 3000');

服务器收到这个请求以后,会将数据放在回调函数的参数位置返回。

1
foo({name: 'uthus'});

由于<script>元素请求的脚本,直接作为代码运行。这时,只要浏览器定义了foo函数,该函数就会立即调用。作为参数的JSON数据被视为JavaScript对象,而不是字符串,因此避免了使用JSON.parse的步骤。

基于Promise,封装一个jsonp工具

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
/**
* 获取随机字符串,用于拼接
* @param {string} prefix [前导名字]
* @param {number} num [字符串长度]
*/
function getRandomName (prefix, num) {
return prefix + Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, num)
}
/**
* 创建script标签
* @param {请求路径} url
*/
function createScript (url) {
const script = document.createElement('script')
script.setAttribute('type', 'text/javascript')
script.setAttribute('src', url)
script.async = true
return script
}
/**
* 实现请求
* @param {路径} url
*/
function jsonp (url) {
return new Promise((resolve, reject) => {
const cbName = getRandomName('callback')
window[cbName] = function (data) {
resolve(data)
}
url += url.indexOf('?') > -1 ? '&' : '?'
const script = createScript(`${url}callback=${cbName}`)
script.onload = function () {
script.onload = null
if (script.parentNode) {
script.parentNode.removeChild(script)
}
window[cbName] = null
}
script.onerror = function () {
reject()
}
document.getElementsByTagName('head')[0].appendChild(script)
})
}

// 调用
jsonp('http://localhost:3000').then(res => {
console.log(res)
}).catch(err => {
console.log(err)
})

2、通过CORS 设置Access-Control-Allow-Origin为’*’

3、Nginx反向代理

参考文章

[‘https://segmentfault.com/a/1190000015597029#articleHeader5']

浏览器同源政策及其规避方法[‘http://www.ruanyifeng.com/blog/2016/04/same-origin-policy.html']

跨域资源共享 CORS 详解[‘http://www.ruanyifeng.com/blog/2016/04/cors.html']

[‘https://segmentfault.com/a/1190000000718840']

面向对象编程

发表于 2018-11-06 | 分类于 前端 |
字数统计: 458 | 阅读时长 ≈ 2

面向对象编程

面向对象的两个基本概念:

  • 类:类是对象的类型模板,例如,定义Student类来表示学生,类本身是一种类型,Student表示学生类型,但不表示任何具体的某个学生;
  • 实例:实例是根据类创建的对象,例如,根据Student类可以创建出xiaoming、xiaohong、xiaojun等多个实例,每个实例表示一个具体的学生,他们全都属于Student类型。

在JS中不区分类和实例的概念,,而是通过原型(prototype)来实现面向对象编程。

创建一个xiaoming对象(通过obj.proto去改变一个对象的原型)

obj.proto去改变一个对象的原型(低版本的IE也无法使用__proto__)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//先创建一个原型对象
var Student = {
name: 'Robot',
height: 1.2,
run: function () {
console.log(this.name + ' is running...');
}
};
//再创建一个xiaoming对象,目前该对象只有name属性
var xiaoming = {
name: '小明'
};
//把xiaoming的原型指向了对象Student,看上去xiaoming仿佛是从Student继承下来的:
//xiaoming现在拥有Student的属性和方法
xiaoming.__proto__ = Student;

// xiaoming.name //'小明'
// Student.name //'Robot'

编写一个函数来创建xiaoming对象(基于Object.create()方法)

Object.create()方法可以传入一个原型对象,并创建一个基于该原型的新对象,但是新对象什么属性都没有

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 原型对象:
var Student = {
name: 'Robot',
height: 1.2,
run: function () {
console.log(this.name + ' is running...');
}
};

function createStudent(name) {
// 基于Student原型创建一个新对象:
var s = Object.create(Student);
// 初始化新对象:
s.name = name;
return s;
}

var xiaoming = createStudent('小明');
xiaoming.run(); // 小明 is running...
xiaoming.__proto__ === Student; // true

原文链接[‘https://www.liaoxuefeng.com/wiki/001434446689867b27157e896e74d51a89c25cc8b43bdb3000/001434499763408e24c210985d34edcabbca944b4239e20000']

创建对象

12…4
Jeffrey Liu

Jeffrey Liu

专注于前端

36 日志
1 分类
10 标签
GitHub E-Mail
© 2017 — 2019 Jeffrey Liu | Site words total count: 29.6k
本站总访问量次 | 本文总阅读量次 |
主题 — NexT.Mist v5.1.3