字符串的扩展 Posted on 2018-08-10 Edited on 2025-07-03 In ECMAScript codePointAt()JavaScript-16 的格式储存,每个字符固定为两个字节。需要四个字节储存的字符,JavaScript 会认为那是两个字符。ES6 提供了 codePointAt 方法,能够正确处理四个字节储存的字符,返回一个字符的码点。 String.fromCodePoint()识别 UTF-32 字符。 includes()、startsWith()、endsWith()1234567var s = "hello world"s.startWith("hello") //trues.endsWith("d") //trues.includes("o") //trues.startsWith("world", 6) //true;s.includes("hello", 6) //false repeat()1234567891011"x".repeat(3) //'xxx'"na".repeat(0) //''"na".repeat(2.9) //取整 -> 'nana'"na".repeat(Infinity) //Error"na".repeat(-1) //Error"na".repeat(-0.9) //''"na".repeat(NaN) //''"na".repeat("3") //'nanana' Read more »
尾调用 Posted on 2018-08-13 Edited on 2025-07-03 In JavaScript 尾调用Tail Call 是函数式编程的一个重要概念,就是指某个函数的最后一步是调用另一个函数。 123function f(x) { return g(x)} 尾调用不一定出现在函数尾部,只要是最后一步操作即可。 1234function f(x) { if (x > 0) return t(x) return m(x)} 尾调用优化函数调用会在内存中形成一个 call frame,保存调用位置和内部变量等信息。所有的 call frame 形成一个 call stack。尾调用由于是函数的最后一步操作,所以不需要保留外层函数的 call frame,这就叫 Tail Call Optimization,即只保留内层函数的调用帧。 尾递归递归非常耗内存,因为需要同时保存多个 call frame,很容易发生 stack overflow。但对于尾递归来说,由于只存在一个 call frame,所以不会发生溢出。 1234567function Fibonacci(n) { if (n <= 1) return 1 return Fibonacci(n - 1) + Fibonacci(n - 2)}console.log(Fibonacci(10)) //89console.log(Fibonacci(100)) //overflowconsole.log(Fibonacci(500)) //overflow Read more »
工厂模式 Posted on 2019-07-09 Edited on 2025-07-03 In JavaScript 工厂模式12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849let Basketball = function () { this.name = 'basketball'}Basketball.prototype = { getMember: function () { console.log(5) }, getBallSize: function () { console.log('big') },}let FootBall = function () { this.name = 'football'}FootBall.prototype = { getMember: function () { console.log(11) }, getBallSize: function () { console.log('big') },}let Tennis = function () { this.name = 'tennis'}Tennis.prototype = { getMember: function () { console.log(1) }, getBallSize: function () { console.log('small') },}let SportFactory = function (name) { switch (name) { case 'basketball': return new Basketball() case 'football': return new FootBall() case 'tennis': return new Tennis() }}let footBall = new SportFactory('football')footBall.getMember() 1234567891011121314151617181920212223242526272829303132333435363738394041424344// Product base attributeinterface Product { operation(): string}class ConcreteProduct1 implements Product { public operation(): string { return 'This is Product1' }}class ConcreteProduct2 implements Product { public operation(): string { return 'This is Product2' }}abstract class Creator { public abstract factoryMethod(): Product public operation(): string { const product = this.factoryMethod() return product.operation() }}class ConcreteCreator1 extends Creator { public factoryMethod(): Product { return new ConcreteProduct1() }}class ConcreteCreator2 extends Creator { public factoryMethod(): Product { return new ConcreteProduct2() }}// usagefunction clientCode(creator: Creator) { console.log(creator.operation())}clientCode(new ConcreteCreator1())clientCode(new ConcreteCreator2()) 安全工厂123456789101112131415161718192021222324252627282930let Factory = function (type, content) { if (this instanceof Factory) { // check if is instance Factory return new this[type](content) } else { return new Factory(type, content) }}Factory.prototype = { Java: function (content) { console.log(content) }, JavaScript: function (content) { console.log(content) },}let data = [ { type: 'Java', content: 'This is Java', }, { type: 'JavaScript', content: 'This is JavaScript', },]// for testfor (let i = 0; i < data.length; i++) Factory(data[i].type, data[i].content) 抽象工厂12345678910111213141516171819202122232425262728293031323334353637383940414243444546/** * to extend superType * @param {*} subType * @param {*} superType */let VehicleFactory = (subType, superType) => { if (typeof VehicleFactory[superType] === 'function') { function F() {} F.prototype = new VehicleFactory[superType]() subType.constuctor = subType subType.prototype = new F() } else { throw new Error("don' not have this abstract class") }}// create base classVehicleFactory.Car = function () { this.type = 'car'}VehicleFactory.Car.prototype = { getPrice: function () { return new Error('abstract') }, getSpeed: function () { return new Error('abstract') },}let BMW = function (price, speed) { this.price = price this.speed = speed}VehicleFactory(BMW, 'Car') // interfaceBMW.prototype = { getPrice: function () { return this.price }, getSpeed: function () { return this.speed },}// for testlet myBmw = new BMW(10000, 100)console.log(myBmw.getPrice()) 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091// product interfaceinterface AbstractProductA { functionA(): string}interface AbstractProductB { /** * base operation * @return {string} */ functionA(): string /** * inject some operation * @param {AbstractProductA} product * @return {string} */ functionB(product: AbstractProductA): string}// concrete productionclass ConcreteProductA1 implements AbstractProductA { functionA(): string { return 'This is functionA from ProductA1' }}class ConcreteProductA2 implements AbstractProductA { functionA(): string { return 'This is functionA from ProductA2' }}class ConcreteProductB1 implements AbstractProductB { functionA(): string { return 'This is functionA from ProductB1' } functionB(product: AbstractProductA): string { return 'Function B2: ' + product.functionA() }}class ConcreteProductB2 implements AbstractProductB { functionA(): string { return 'This is functionA from ProductB2' } functionB(product: AbstractProductA): string { return 'Function B2: ' + product.functionA() }}// factory interfaceinterface AbstractFactory { createProductA(): AbstractProductA createProductB(): AbstractProductB}// concrete factoryclass ConcreteFactory1 implements AbstractFactory { createProductA(): AbstractProductA { return new ConcreteProductA1() } createProductB(): AbstractProductB { return new ConcreteProductB1() }}class ConcreteFactory2 implements AbstractFactory { createProductA(): AbstractProductA { return new ConcreteProductA2() } createProductB(): AbstractProductB { return new ConcreteProductB2() }}// usage/** * use with different facotry. * @param {AbstractFactory} factory */function clientCode(factory: AbstractFactory) { const productA = factory.createProductA() const productB = factory.createProductB() console.log(productB.functionA()) console.log(productB.functionB(productA))}clientCode(new ConcreteFactory1())clientCode(new ConcreteFactory2())
巴黎圣母院大火 Posted on 2019-04-16 Edited on 2025-07-03 又一次的见证历史。 卡西莫多失去了他心爱的姑娘,也失去了他心爱的钟楼。 废墟中的十字架依旧闪发着光芒 PS: 看到一条推,说你看大火都没有把十字架给损毁,难道你还不相信上帝吗?下面回:因为金的熔点比木高很多。XD
并查集 Posted on 2019-03-13 Edited on 2025-07-03 In Data Structure 并查集用集合中的某个元素来代表这个集合,该元素称为集合的代表元。一个集合内的所有元素组织成以代表元为根的树形结构。对于每一个元素parent[x]指向 x 在树形结构上的父亲节点。如果 x 是根节点,则令parent[x] = x。对于查找操作,假设需要确定 x 所在的的集合,也就是确定集合的代表元。可以沿着parent[x]不断在树形结构中向上移动,直到到达根节点。 Read more »