Coder Social home page Coder Social logo

blog's Introduction

blog's People

Contributors

kian-404 avatar

blog's Issues

js模拟实现一个栈

首先我们来看一下什么是栈

“栈是一种遵从后进先出(LIFO)原则的有序集合。新添加的或待删除的元素都保存在栈的同一端,称作栈顶,另一端就叫栈底。在栈里,新元素都靠近栈顶,旧元素都接近栈底。”

接下来,要为我们的栈声明一些方法。

  • push(element(s)):添加一个(或几个)新元素到栈顶。

  • pop():移除栈顶的元素,同时返回被移除的元素。

  • peek():返回栈顶的元素,不对栈做任何修改(这个方法不会移除栈顶的元素,仅仅返回它)。

  • isEmpty():如果栈里没有任何元素就返回true,否则返回false。

  • clear():移除栈里的所有元素。

  • size():返回栈里的元素个数。这个方法和数组的length属性很类似。

class Stack {
	constructor() {
		this.item = [];
	}

	push(element) {
		this.item.push(element);
	}

	pop() {
		return this.item.pop();
	}

	peek() {
		return this.item[this.item.length -1 ];
	}

	isEmpty() {
		return this.item.length === 0;
	}

	size() {
		return this.item.length;
	}

	clear() {
		this.item = [];
	}

	print() {
		console.log(this.item);
	}
}

那么我们能用栈解决什么问题吗
下面来看一下用栈来解决进制转换问题

function baseConverter(decNumber, base) {
	var remStack = new Stack(),
		rem,
		brnaryString = '',
		digits = '0123456789ABCDEF';

	while (decNumber > 0) {
		rem = Math.floor(decNumber % base);
		remStack.push(rem);
		decNumber = Math.floor(decNumber / base);

	}

	while (!remStack.isEmpty()) {
		brnaryString += digits[remStack.pop()]
	}
	return brnaryString;
}
console.log(baseConverter(12, 2)) //1100
console.log(baseConverter(12, 8)) //14
console.log(baseConverter(12, 16)) //C

js模拟实现一个Set集合

集合是由一组无序且唯一(即不能重复)的项组成的。


  • add(value):向集合添加一个新的项。

  • delete(value):从集合移除一个值。

  • has(value):如果值在集合中,返回true,否则返回false。

  • clear():移除集合中的所有项。

  • size():返回集合所包含元素的数量。与数组的length属性类似。

  • values():返回一个包含集合中所有值的数组。


并集:对于给定的两个集合,返回一个包含两个集合中所有元素的新集合。

交集:对于给定的两个集合,返回一个包含两个集合**有元素的新集合。

差集:对于给定的两个集合,返回一个包含所有存在于第一个集合且不存在于第二个集合的元素的新集合。

子集:验证一个给定集合是否是另一集合的子集。


class Set {
	constructor() {
		this.items = {};
	}

	has(value) {
		return this.items.hasOwnProperty(value);
	}

	add(value) {
		if (!this.has(value)) {
			this.items[value] = value;
			return true;
		} else {
			return false;
		}
	}

	remove(value) {
		if (this.has(value)) {
			delete this.items[value];
			return true;
		} else {
			return false;
		}
	}

	clear() {
		this.items = {};
	}

	size() {
		let count = 0;
		for (let key in this.items) {
			if (this.items.hasOwnProperty(key)) {
				++count;
			}
		}
		return count;
	}

	keys() {
		let keys = [];
		for (let key in this.items) {
			if (this.items.hasOwnProperty(key)) {
				keys.push(key);
			}
		}
		return keys;
	}

	values() {
		let values = [];
		for (let value in this.items) {
			if (this.items.hasOwnProperty(value)) {
				values.push(this.items[value]);
			}
		}
		return values;
	}

}
// 并集 A U B
Set.prototype.union = function (otherSet) {
	let unionSet = new Set();
	let values = this.values();
	for (let i = 0; i < values.length; i++) {
		unionSet.add(values[i]);
	}
	values = otherSet.values();
	for (let i = 0; i < values.length; i++) {
		unionSet.add(values[i]);
	}
	return unionSet;
}

// 交集 A ∩ B
Set.prototype.intersection = function (otherSet) {
	let intersectionSet = new Set();
	let values = this.values();

	for (let i = 0; i < values.length; i++) {
		if (otherSet.has(values[i])) {
			intersectionSet.add(values[i]);
		}
	}
	return intersectionSet;
}

// 差集 A-B
Set.prototype.difference = function (otherSet) {
	let differenceSet = new Set();
	let values = this.values();

	for (let i = 0; i < values.length; i++) {
		if (!otherSet.has(values[i])) {
			differenceSet.add(values[i]);
		}
	}
	return differenceSet;
}

// 子集 A⊆B
Set.prototype.subset = function (otherSet) {
	if (this.size() > otherSet.size()) {
		return false;
	} else {
		let values = this.values();
		for (let i = 0; i < values.length; i++) {
			if (!otherSet.has(values[i])) {
				return false;
			}
		}
		return true;
	}
}

let set = new Set();
set.add(1);
set.add(2);
// set.add(5);
// set.add(9);
console.log(set); // Set { items: { '1': 1, '2': 2 } }
console.log(set.keys()); // [ '1', '2' ]
console.log(set.values()); // [ 1, 2 ]
console.log(set.size()); // 2
set.remove(1);
console.log(set); // Set { items: { '2': 2 } }
let otherset = new Set();
otherset.add(1);
otherset.add(2);
otherset.add(3);
otherset.add(4);
console.log(set.union(otherset)); // Set { items: { '1': 1, '2': 2, '3': 3, '4': 4 } }
console.log(set.intersection(otherset)); //Set { items: { '2': 2 } }
console.log(set.difference(otherset)); // Set { items: {} }
console.log(set.subset(otherset)); // true

js模拟实现call,apply,bind

Function.prototype.call()

语法

fun.call(thisArg, arg1, arg2, ...)

参数

  • thisArg

在fun函数运行时指定的this值。需要注意的是,指定的this值并不一定是该函数执行时真正的this值,如果这个函数处于non-strict mode,则指定为null和undefined的this值会自动指向全局对象(浏览器中就是window对象),同时值为原始值(数字,字符串,布尔值)的this会指向该原始值的自动包装对象。
arg1, arg2, ... 指定的参数列表。

  • 返回值

使用调用者提供的this值和参数调用该函数的返回值。若该方法没有返回值,则返回undefined。


Function.prototype.apply()

语法

func.apply(thisArg, [argsArray])

参数

  • thisArg

可选的。在 func 函数运行时使用的 this 值。请注意,this可能不是该方法看到的实际值:如果这个函数处于非严格模式下,则指定为null 或 undefined 时会自动替换为指向全局对象,原始值会被包装。
argsArray 可选的。一个数组或者类数组对象,其中的数组元素将作为单独的参数传给 func 函数。如果该参数的值为 null 或 undefined,则表示不需要传入任何参数。从ECMAScript 5 开始可以使用类数组对象。

返回值

调用有指定this值和参数的函数的结果。


Function.prototype.bind()

语法

function.bind(thisArg[, arg1[, arg2[, ...]]])

参数

  • thisArg

调用绑定函数时作为this参数传递给目标函数的值。
如果使用new运算符构造绑定函数,则忽略该值。当使用bind在setTimeout中创建一个函数(作为回调提供)时,作为thisArg传递的任何原始值都将转换为object。如果bind函数的参数列表为空,执行作用域的this将被视为新函数的thisArg。
arg1, arg2, ... 当目标函数被调用时,预先添加到绑定函数的参数列表中的参数。

返回值

返回一个原函数的拷贝,并拥有指定的this值和初始参数。


模拟实现如下:

Function.prototype.mycall = function(context) {
	var context = context || window;
	// 给context添加一个属性
	context.fn = this;
	// 获取参数
	var args = [...arguments].slice(1);
	// 执行该函数
	var result = context.fn(...args);
	// 删除fn	
	delete context.fn;
	// 返回执行结果
	return result;
}

Function.prototype.myapply = function(context) {
	var context = context || window;

	context.fn = this;

	var result = null;

	if(arguments[1]) {
	
		result = context.fn(...arguments);
		
	}else {
	
		result = context.fn();
		
	}
	
	delete context.fn;

	return result;
}

Function.prototype.mybind = function(context) {
	if(typeof this !== 'function') {
	
		throw new TypeError('Error');
		
	}
	
	var _this = this;

	var args = [...arguments].slice(1);

	return function F() {
	
		if(this instanceof F) {
		
			return new _this(...args, ...arguments);
			
		}
		
		return _this.apply(context, args.concat(...arguments));
		
	}
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.