单例模式

单例模式是指每一个类只会生成一个实例,这样可以节省开销,也容易进行业务管理,首先以TS来一段单例实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Scene{
public name:string;
private static instance:Scene;
private constructor(name:string){
this.name = name;
}

public static getInstance():Scene{
if(!Scene.instance){
Scene.instance = new Scene("Jonny");
}
return Scene.instance;
}

}

//let a = new Scene("jonny"); //编译错误
let a = Scene.getInstance();
let b = Scene.getInstance();

console.log(a===b); //true

阅读更多

对象创建模式

如何在ES5中实现私有成员

1
2
3
4
5
6
7
8
9
10
function Gadget(){
var name = "jonny";
this.getName = function (){
return name;
}
}

var toy = new Gadget();
console.log(toy.name); //undefined
console.log(toy.getName()); //jonny

当私有成员是一个对象时,公共方法会暴露对象引用,实例会通过引用对私有成员进行修改,从而导致私有成员的失效

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function Gadget(){
var box = {
x:10,
y:10
}
this.getBox = function (){
return box;
}
}

var toy = new Gadget();
console.log(toy.box); //undefined
console.log(toy.getBox()); //返回{x:10,y:10}
let box = toy.getBox();
box.x = 20;
console.log(toy.getBox());//{x:20,y:10}

原型模式

为了节省开支与避免重复复制相同的成员与方法,一般会把常用的成员与方法放进原型中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function Xbox(){
var name = "Mic";
this.getName = function (){
return name;
}
}

Xbox.prototype = (function (){
var browser = 'webKit';
return {
getBrowser:function (){
return browser;
}
}
}())

var toy = new Xbox();
toy.getName(); //mic
toy.getBrowser(); //webkit

揭示模块模式

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
var module;

(function (){
var color = 0xff0000;
var position = {
x:0,
y:0
}
var size = {
w:100,
h:100
}
var rectAngle = function (){
return {
x:position.x,
y:position.y,
w:position.x + size.w,
h:position.y + size.h
}
}
module = {
color:color,
position:position,
size:size,
rectAngle:rectAngle
}
})()

闭包实现私有静态方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var Uid = (function (){
var count = 0;
var newUid = function (){
count+=1;
};
newUid.prototype.getUid = function (){
return count;
}
return newUid;
})()

var a = new Uid();
a.getUid();// 1
var b = new Uid();
b.getUid();// 2

ES5常量实现

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
var constant = (function (){
var constants = {},
ownProp = Object.prototype.hasOwnProperty,
allowed = {
string:1,
number:1,
boolean:1
},
prefix = (Math.random() + '_').slice(2);
return {
set:function (name,value){
if(this.isDefined(name)){
return false;
}
if(!ownProp.call(allowed,typeof value)){
return false;
}
constants[prefix + name] = value;
return true;
},
get:function (name){
if(this.isDefined(name)){
return constants[orefix + name];
}else{
return null;
}
},
isDefined:function (name){
return ownProp.call(constants,prefix + name);
}
}
})()

颜色分类

给定一个包含红色、白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。

此题中,我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。

注意:
不能使用代码库中的排序函数来解决这道题。

示例:

输入: [2,0,2,1,1,0]
输出: [0,0,1,1,2,2]

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
/**
* @param {number[]} nums
* @return {void} Do not return anything, modify nums in-place instead.
*/
var sortColors = function (nums) {
let p0 = 0; //指向0的偏移量,交换元素后向后偏移
let p1 = 0; //指向1的偏移量,交换元素后向后偏移
nums.forEach((x, i) => {
//当x==1,交换元素,只偏移p1
if(x === 1){
[nums[p1], nums[i]] = [nums[i], nums[p1]];
++p1;
}
//当x==0,交换元素,整体偏移
if (x === 0) {
[nums[p0], nums[i]] = [nums[i], nums[p0]];
// 当发生p0小于p1时,再循环p1
if(p0<p1){
[nums[p1], nums[i]] = [nums[i], nums[p1]];
}
++p0;
++p1;
}
})
}

phaser的魔性

首先,不是在数落某个引擎不好,但不代表所有的事物都是完美的,phaser的V3版本去除了PIXI渲染引擎,更新频率有点大,也在完善之中,phaser的编程风格是比较偏于过程化的,但是并不代表不可以按照面向对象的风格去进行,但是会添加额外的代码,我仍然认为,面向对象依然是维护一套方案最好的编程风格;

container中的sprite无法更新动画

阅读更多

判断浏览器用户代理

见代码

1
2
3
4
5
6
7
8
9
var weixin = is_weixin();
function is_weixin(){
var ua = navigator.userAgent.toLowerCase();
if(ua.match(/MicroMessenger/i)=="micromessenger") {
return true;
} else {
return false;
}
};

h5禁止缩放与双击选中

网上的常规都是这样

1
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">

但是在ios上是不行的,看了ionic的元数据后,发现需要加一句viewport-fit=cover,发现可行,见全部

1
<meta name="viewport" content="viewport-fit=cover, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">

vsc.config配置

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
{
"editor.quickSuggestions": {
"other": false,
"comments": false,
"strings": false
},
"editor.suggest.snippetsPreventQuickSuggestions": false,
"editor.acceptSuggestionOnCommitCharacter": false,
"editor.suggestOnTriggerCharacters": false,
"editor.wordBasedSuggestions": false,
"editor.fontFamily": "Courier New",
"editor.fontSize": 18,
"editor.selectionHighlight": false,
"editor.renderLineHighlight": "none",
"editor.wordWrap": "on",
"files.associations": {
"*.cjson": "jsonc",
"*.wxss": "css",
"*.wxs": "javascript"
},
"emmet.includeLanguages": {
"wxml": "html"
},
"workbench.colorTheme": "Base16 Tomorrow Dark",
"editor.codeLens": false,
"editor.colorDecorators": false,
"editor.highlightActiveIndentGuide": false,
"editor.folding": true,
"editor.renderIndentGuides": false,
"editor.hover.delay": 1000,
"workbench.startupEditor": "newUntitledFile",
"terminal.integrated.fontSize": 14,
"terminal.integrated.lineHeight": 1.2,
"workbench.colorCustomizations": {
"editor.background": "#000000"
},
"typescript.updateImportsOnFileMove.enabled": "always",
"workbench.editor.enablePreview": false,
"window.zoomLevel": 0,
"breadcrumbs.enabled": true,
"editor.minimap.enabled": false,
"javascript.updateImportsOnFileMove.enabled": "always",
"terminal.integrated.rendererType": "dom",
"update.enableWindowsBackgroundUpdates": false,
"extensions.autoUpdate": false
}