return new Segment(Math.pow(v1, v2));
}
};
}
//Class for special functions
function MathFunction(input) {
this.f = input;
if (!input) {
console.log(“Math function has no input.”);
}
this.solve = function (segment) {
var v = segment.coefficient;
if (this.f == “sin”) {
return new Segment(Math.sin(v));
} else if (this.f == “cos”) {
return new Segment(Math.cos(v));
} else if (this.f == “tan”) {
return new Segment(Math.tan(v));
} else if (this.f == “asin”) {
return new Segment(Math.asin(v));
} else if (this.f == “acos”) {
return new Segment(Math.acos(v));
} else if (this.f == “atan”) {
return new Segment(Math.atan(v));
} else if (this.f == “abs”) {
return new Segment(Math.abs(v));
}
};
}
//Class for a segment of math (a container)
function Segment(input) {
this.sections = [];
this.type = “section”;
this.operator = 0;
this.coefficient = 0;
this.mathFunction = 0;
this.variable = “”;
var removeBrackets = function (value) {
if (!value) return “”;
//While there are brackets around the string
while (value.substr(0, 1) == “(” && value.substr(value.length - 1, 1) == “)”) {
var openBrackets = 1;
//See if the end bracket closes the opening bracket or not
for (var i = 1; i < value.length && openBrackets > 0; i++) {
if (value.substr(i, 1) == “(”) openBrackets++;
if (value.substr(i, 1) == “)”) openBrackets–;
}
i -= 1;
//If it corresponds to different brackets, do nothing
if (openBrackets !== 0 || i != value.length - 1) {
break;
//Otherwise, remove the brackets, continue loop to see if there are more
} else {
value = value.substring(1, value.length - 1);
}
}
return value;
};
var findLast = function (operator, value) {
//Keep searching for the next last sign if the one found is within brackets
var inBrackets = true;
var index = -1;
if (operator != “^”) {
index = value.lastIndexOf(operator);
} else {
index = value.indexOf(operator); //Look for the first instead of last if it’s an exponent
}
var operators = “±/*^”;
while (inBrackets) {
var openBrackets = 0;
//Find how many brackets are opened or closed at a given point in the string
for (var i = 0; i < value.length; i++) {
if (value.substr(i, 1) == “(”) {
openBrackets++;
} else if (value.substr(i, 1) == “)”) {
openBrackets–;
}
if (i == index) {
//If no brackets are open (and if the operator is actually - and not just a minus sign), break the loop.
if ((openBrackets === 0 && (operator != “-” || (i > 0 && operators.indexOf(value.substr(i - 1, 1)) == -1) || i === 0)) || (openBrackets == 1 && operator == “(”)) {
inBrackets = false;
break;
//Otherwise, find the next operator, and loop through again to see if that one is in brackets
} else {
if (operator != “^”) {
index = value.substring(0, index).lastIndexOf(operator);
} else {
var nextOperator = value.substring(index + 1).indexOf(operator);
if (nextOperator == -1) {
index = -1;
} else {
index = (index + 1 + value.substring(index + 1).indexOf(operator));
}
}
}
}
}
//If no more operators are found, break the loop
if (index == -1) {
inBrackets = false;
}
}
return index;
};
var findLastTrig = function (trig, value) {
var matches = 0;
var index = -1;
var r = 0;
if (trig == “sin”) {
r = /(a)?sin/g;
} else if (trig == “cos”) {
r = /(a)?cos/g;
} else if (trig == “tan”) {
r = /(a)?tan/g;
} else {
return -1;
}
for (matches = r.exec(value); matches; matches = r.exec(value)) if (RegExp.$1 != “a”) index = matches.index;
var inBrackets = true;
while (inBrackets && index != -1) {
var openBrackets = 0;
//Find how many brackets are opened or closed at a given point in the string
for (var i = 0; i < value.length; i++) {
if (value.substr(i, 1) == “(”) {
openBrackets++;
} else if (value.substr(i, 1) == “)”) {
openBrackets–;
}
if (i == index) {
//If no brackets are open (and if the operator is actually - and not just a minus sign), break the loop.
if (openBrackets === 0) {
inBrackets = false;
break;
//Otherwise, find the next operator, and loop through again to see if that one is in brackets
} else {
var sub = value.substring(0, index);
index = -1;
for (matches = r.exec(sub); matches; matches = r.exec(sub)) if (RegExp.$1 != “a”) index = matches.index;
}
}
}
//If no more operators are found, break the loop
if (index == -1) {
inBrackets = false;
}
}
return index;
};
//Specifically for finding brackets that can be used for multiplication
var findMultiplicationBrackets = function (value) {
//Keep searching for the next last sign if the one found is within brackets
var inBracketsOpen = true;
var inBracketsClosed = true;
var indexOpen = -1;
var indexClosed = -1;
var operators = “±/*^sincostanabs”;
indexOpen = value.lastIndexOf(“(”);
indexClosed = value.lastIndexOf(“)”);
while (inBracketsOpen || inBracketsClosed) {
var openBrackets = 0;
//Find how many brackets are opened or closed at a given point in the string
for (var i = 0; i < value.length; i++) {
if (value.substr(i, 1) == “(”) {
openBrackets++;
} else if (value.substr(i, 1) == “)”) {
openBrackets–;
}
if (i == indexOpen && inBracketsOpen) {
if (openBrackets == 1 && i !== 0 && operators.indexOf(value.substr(i - 1, 1)) == -1) {
inBracketsOpen = false;
//Otherwise, find the next operator, and loop through again to see if that one is in brackets
} else {
indexOpen = value.substring(0, indexOpen).lastIndexOf(“(”);
}
}
if (i == indexClosed && inBracketsClosed) {
if (openBrackets === 0 && i < value.length - 1 && operators.indexOf(value.substr(i + 1, 1)) == -1) {
inBracketsClosed = false;
//Otherwise, find the next operator, and loop through again to see if that one is in brackets
} else {
indexClosed = value.substring(0, indexClosed).lastIndexOf(“)”);
}
}
}
//If no more operators are found, break the loop
if (indexOpen == -1) {
inBracketsOpen = false;
}
if (indexClosed == -1) {
inBracketsClosed = false;
}
}
if (indexClosed > indexOpen && indexClosed != -1) {
return indexClosed;
} else {
return indexOpen;
}
};
//Recursively solve children
this.solve = function (x) {
if (!x) x = 0;
if (this.type == “value”) {
return this;
} else if (this.type == “variable”) {
return new Segment(x);
} else if (this.type == “function”) {
return this.mathFunction.solve(this.sections[0].solve(x));
} else {
if (this.sections.length == 1) {
return this.sections[0].solve(x);
} else if (this.sections.length == 2) {
return this.operator.solve(this.sections[0].solve(x), this.sections[1].solve(x), x);
}
}
};
//Outputs the final answer
this.result = function (x) {
return this.solve(x).coefficient;
};
this.display = function (x) {
if (this.type == “value”) return this.coefficient;
if (this.type == “variable”) return “x”;
if (this.type == “function”) return this.mathFunction.f;
var str = “
”;for (var i = 0; i < this.sections.length; i++) {
str += this.sections[i].display(x);
if (i === 0 && this.operator) {
str += “
” + this.operator.operator + “ ”;}
}
str += "
= " + this.solve().coefficient + “ ”;str += “”;
return str;
};
//constructor
if (input !== undefined) {
if (typeof (input) == “string”) {
//Remove excess whitespace
input = input.replace(/\s/g, “”);
//get rid of unnecessary brackets surrounding the section
input = removeBrackets(input);
//Find the last instance of each operator in the string
var addition = findLast(“+”, input);
var subtraction = findLast(“-”, input);
var division = findLast(“/”, input);
var exponent = findLast(“^”, input); //Find the first exponent, since those work in reverse
var bracket1 = findLast(“(”, input);
var sin = findLastTrig(“sin”, input);
var cos = findLastTrig(“cos”, input);
var tan = findLastTrig(“tan”, input);
var asin = findLast(“asin”, input);
var acos = findLast(“acos”, input);
var atan = findLast(“atan”, input);
var abs = findLast(“abs”, input);
var multiplication = findLast(“*”, input);
var multiplication2 = findMultiplicationBrackets(input); //Find brackets that are the same as multiplication
var functionMultiplication = -1;
if (sin > multiplication) functionMultiplication = sin;
if (cos > multiplication) functionMultiplication = cos;
if (tan > multiplication) functionMultiplication = tan;
if (asin > multiplication) functionMultiplication = asin;
if (acos > multiplication) functionMultiplication = acos;
if (atan > multiplication) functionMultiplication = atan;
if (abs > multiplication) functionMultiplication = abs;
//Push back each half of the equation into a section, in reverse order of operations
if (addition != -1 && (subtraction == -1 || addition > subtraction)) {
this.sections.push(new Segment(input.substring(0, addition)));
this.sections.push(new Segment(input.substring(addition + 1)));
this.operator = new Operator(“+”);
} else if (subtraction != -1) {
if (subtraction > 0) {
this.sections.push(new Segment(input.substring(0, subtraction)));
} else {
this.sections.push(new Segment(0));
}
this.sections.push(new Segment(input.substring(subtraction + 1)));
this.operator = new Operator(“-”);
} else if (functionMultiplication > 0 && functionMultiplication > multiplication && functionMultiplication > division) {
this.sections.push(new Segment(input.substring(0, functionMultiplication)));
this.sections.push(new Segment(input.substring(functionMultiplication)));
this.operator = new Operator(“*”);
} else if (multiplication2 != -1 && (division == -1 || multiplication > division) && (multiplication == -1 || multiplication2 > multiplication)) {
this.sections.push(new Segment(input.substring(0, multiplication2)));
this.sections.push(new Segment(input.substring(multiplication2)));
this.operator = new Operator(“*”);
} else if (multiplication != -1 && (division == -1 || multiplication > division)) {
this.sections.push(new Segment(input.substring(0, multiplication)));
this.sections.push(new Segment(input.substring(multiplication + 1)));
this.operator = new Operator(“*”);
} else if (division != -1) {
this.sections.push(new Segment(input.substring(0, division)));
this.sections.push(new Segment(input.substring(division + 1)));
this.operator = new Operator(“/”);
} else if (exponent != -1) {
this.sections.push(new Segment(input.substring(0, exponent)));
this.sections.push(new Segment(input.substring(exponent + 1)));
this.operator = new Operator(“^”);
} else if (sin != -1 && (cos == -1 || sin > cos) && (tan == -1 || sin > tan) && (asin == -1 || sin > asin) && (acos == -1 || sin > acos) && (atan == -1 || sin > atan) && (abs == -1 || sin > abs)) {
this.sections.push(new Segment(input.substring(sin + 3)));
this.mathFunction = new MathFunction(“sin”);
this.type = “function”;
} else if (cos != -1 && (tan == -1 || cos > tan) && (asin == -1 || cos > asin) && (acos == -1 || cos > acos) && (atan == -1 || cos > atan) && (abs == -1 || cos > abs)) {
this.sections.push(new Segment(input.substring(cos + 3)));
this.mathFunction = new MathFunction(“cos”);
this.type = “function”;
} else if (tan != -1 && (asin == -1 || tan > asin) && (acos == -1 || tan > acos) && (atan == -1 || tan > atan) && (abs == -1 || tan > abs)) {
this.sections.push(new Segment(input.substring(tan + 3)));
this.mathFunction = new MathFunction(“tan”);
this.type = “function”;
} else if (asin != -1 && (acos == -1 || asin > acos) && (atan == -1 || asin > atan) && (abs == -1 || asin > abs)) {
this.sections.push(new Segment(input.substring(asin + 4)));
this.mathFunction = new MathFunction(“asin”);
this.type = “function”;
} else if (acos != -1 && (atan == -1 || acos > atan) && (abs == -1 || acos > abs)) {
this.sections.push(new Segment(input.substring(acos + 4)));
this.mathFunction = new MathFunction(“acos”);
this.type = “function”;
} else if (atan != -1 && (abs == -1 || atan > abs)) {
this.sections.push(new Segment(input.substring(atan + 4)));
this.mathFunction = new MathFunction(“atan”);
this.type = “function”;
} else if (abs != -1) {
this.sections.push(new Segment(input.substring(abs + 3)));
this.mathFunction = new MathFunction(“abs”);
this.type = “function”;
} else if (bracket1 != -1) {
var openBrackets = 1;
for (var i = bracket1 + 1; i < input.length && openBrackets > 0; i++) {
if (input.substr(i, 1) == “(”) openBrackets++;
if (input.substr(i, 1) == “)”) openBrackets–;
}
if (openBrackets === 0) {
var bracket2 = i - 1;
if (bracket1 > 0) this.sections.push(new Segment(input.substring(0, bracket1)));
if (bracket2 - bracket1 != 1) this.sections.push(new Segment(input.substring(bracket1 + 1, bracket2)));
if (bracket2 != input.length - 1) this.sections.push(new Segment(input.substring(bracket2 + 1)));
this.operator = new Operator(“*”);
} else {
console.log("Brackets nesting error: " + input);
}
//If there are no operators, just push the input itself
} else {
var xLocation = input.toLowerCase().indexOf(“x”);
if (xLocation != -1) {
if (xLocation > 0) {
this.sections.push(new Segment(input.substring(0, xLocation)));
this.sections.push(new Segment(“x”));
this.operator = new Operator(“*”);
} else {
this.variable = “x”;
this.type = “variable”;
}
} else {
this.coefficient = parseFloat(input);
this.type = “value”;
}
}
} else if (typeof (input) == “number”) {
this.coefficient = input;
this.type = “value”;
}
} else {
console.log(“Segment has no input.”);
}
}
//One point on a graph
function Point(x, y) {
this.x = x || 0;
this.y = y || 0;
}
//MathFunction to create graphs
function Graph(value, width, height, rangeX, rangeY) {
var autoRange = false;
//Default params
if (rangeX === undefined) {
rangeX = 10;
}
if (rangeY === undefined) {
autoRange = true;
}
//Properties
this.expression = new Segment(value);
this.points = [];
this.canvas = document.createElement(“canvas”);
this.canvas.width = width || 800;
this.canvas.height = height || 800;
this.min = undefined;
this.max = undefined;
this.x1 = 0 - Math.abs(rangeX);
this.x2 = 0 + Math.abs(rangeX);
this.y1 = 0 - Math.abs(rangeY);
this.y2 = 0 + Math.abs(rangeY);
var startMouse = new Point(0, 0);
var mousePos = new Point(0, 0);
var timer = 0;
var stage = 0;
var img = 0;
var magnitudeX = 0;
var magnitudeY = 0;
//Gets minimum y value in the set of points
this.getMin = function () {
if (this.min === undefined) {
if (this.points.length > 0) {
var min = this.points[0].y;
for (var i = 1; i < this.points.length; i++) {
if (this.points[i].y < min) min = this.points[i].y;
}
this.min = min;
return min;
} else {
return 0;
}
} else {
return this.min;
}
};
//Gets maximum y value in the set of points
this.getMax = function () {
if (this.max === undefined) {
if (this.points.length > 0) {
var max = this.points[0].y;
for (var i = 1; i < this.points.length; i++) {
if (this.points[i].y > max) max = this.points[i].y;
}
this.max = max;
return max;
} else {
return 0;
}
} else {
return this.max;
}
};
//Updates the points and graph
this.update = function () {
var accuracy = (this.x2 - this.x1) / this.canvas.width;
this.points = [];
for (var i = this.x1; i <= this.x2; i += accuracy) {
this.points.push(new Point(i, this.expression.result(i)));
}
if (autoRange) {
if (this.getMax() - this.getMin() > 100000) {
this.y1 = -100;
this.y2 = 100;
} else {
this.y1 = this.getMin() - 5;
this.y2 = this.getMax() + 5;
}
autoRange = false;
}
magnitudeX = Math.ceil(Math.log(this.x2 - this.x1));
magnitudeY = Math.ceil(Math.log(this.y2 - this.y1));
this.redraw();
};
var drawAxes = function (_x1, _x2, _y1, _y2, redraw) {
stage.strokeStyle = “#7FFF00”;
stage.fillStyle = “#7FFF00”;
var limit = 0;
var i = 0;
//Draw the y axis if it is in the view
if (0 >= _x1 - 30 && 0 <= _x2 + 30) {
stage.lineWidth = 2;
stage.beginPath();
stage.moveTo(this.canvas.width / 2 - (((_x2 + _x1) / 2) / (_x2 - _x1)) * this.canvas.width, 0);
stage.lineTo(this.canvas.width / 2 - (((_x2 + _x1) / 2) / (_x2 - _x1)) * this.canvas.width, this.canvas.height);
stage.closePath();
stage.stroke();
stage.textAlign = “right”;
stage.textBaseline = “middle”;
stage.lineWidth = 1;
limit = (Math.abs(_y2) > Math.abs(_y1)) ? Math.abs(_y2) : Math.abs(_y1);
for (i = 0; i <= limit; i += Math.pow(10, Math.floor(Math.log(_y2 - _y1) / Math.LN10)) / 4) {
if (i === 0) continue;
if (i <= _y2 + 50) {
if (redraw || (i >= this.y2 - 50)) {
stage.beginPath();
stage.moveTo(this.canvas.width / 2 - (((_x2 + _x1) / 2) / (_x2 - _x1)) * this.canvas.width - 5, this.canvas.height - ((i - _y1) / (_y2 - _y1)) * this.canvas.height);
stage.lineTo(this.canvas.width / 2 - (((_x2 + _x1) / 2) / (_x2 - _x1)) * this.canvas.width + 5, this.canvas.height - ((i - _y1) / (_y2 - _y1)) * this.canvas.height);
stage.closePath();
stage.stroke();
stage.fillText(“” + (Math.round(i * 100) / 100), this.canvas.width / 2 - (((_x2 + _x1) / 2) / (_x2 - _x1)) * this.canvas.width - 8, this.canvas.height - ((i - _y1) / (_y2 - _y1)) * this.canvas.height);
}
}
if (i >= _y1 - 50) {
if (redraw || (-i <= this.y1 + 50)) {
stage.beginPath();
stage.moveTo(this.canvas.width / 2 - (((_x2 + _x1) / 2) / (_x2 - _x1)) * this.canvas.width - 5, this.canvas.height - ((-i - _y1) / (_y2 - _y1)) * this.canvas.height);
stage.lineTo(this.canvas.width / 2 - (((_x2 + _x1) / 2) / (_x2 - _x1)) * this.canvas.width + 5, this.canvas.height - ((-i - _y1) / (_y2 - _y1)) * this.canvas.height);
stage.closePath();
stage.stroke();
stage.fillText(“” + (Math.round(-i * 100) / 100), this.canvas.width / 2 - (((_x2 + _x1) / 2) / (_x2 - _x1)) * this.canvas.width - 8, this.canvas.height - ((-i - _y1) / (_y2 - _y1)) * this.canvas.height);
}
}
}
}
//Draw the x axis if it is in the view
if (0 >= _y1 - 50 && 0 <= _y2 + 50) {
stage.lineWidth = 2;
stage.beginPath();
stage.moveTo(0, this.canvas.height / 2 + (((_y2 + _y1) / 2) / (_y2 - _y1)) * this.canvas.height);
stage.lineTo(this.canvas.width, this.canvas.height / 2 + (((_y2 + _y1) / 2) / (_y2 - _y1)) * this.canvas.height);
stage.closePath();
stage.stroke();
stage.textAlign = “center”;
stage.textBaseline = “top”;
stage.lineWidth = 1;
limit = (Math.abs(_x2) > Math.abs(_x1)) ? Math.abs(_x2) : Math.abs(_x1);
for (i = 0; i <= limit; i += Math.pow(10, Math.floor(Math.log(_x2 - _x1) / Math.LN10)) / 4) {
if (i === 0) continue;
if (i <= _x2 + 50) {
if (redraw || (i >= this.x2 - 50)) {
stage.beginPath();
stage.moveTo(((i - _x1) / (_x2 - _x1)) * this.canvas.width, this.canvas.height / 2 + (((_y2 + _y1) / 2) / (_y2 - _y1)) * this.canvas.height - 5);
stage.lineTo(((i - _x1) / (_x2 - _x1)) * this.canvas.width, this.canvas.height / 2 + (((_y2 + _y1) / 2) / (_y2 - _y1)) * this.canvas.height + 5);
stage.closePath();
stage.stroke();
stage.fillText(“” + (Math.round(i * 100) / 100), ((i - _x1) / (_x2 - _x1)) * this.canvas.width, this.canvas.height / 2 + (((_y2 + _y1) / 2) / (_y2 - _y1)) * this.canvas.height + 8);
}
}
if (i >= _x1 - 50) {
if (redraw || (-i <= this.x1 + 50)) {
stage.beginPath();
stage.moveTo(((-i - _x1) / (_x2 - _x1)) * this.canvas.width, this.canvas.height / 2 + (((_y2 + _y1) / 2) / (_y2 - _y1)) * this.canvas.height - 5);
stage.lineTo(((-i - _x1) / (_x2 - _x1)) * this.canvas.width, this.canvas.height / 2 + (((_y2 + _y1) / 2) / (_y2 - _y1)) * this.canvas.height + 5);
stage.closePath();
stage.stroke();
stage.fillText(“” + (Math.round(-i * 100) / 100), ((-i - _x1) / (_x2 - _x1)) * this.canvas.width, this.canvas.height / 2 + (((_y2 + _y1) / 2) / (_y2 - _y1)) * this.canvas.height + 8);
}
}
}
}
}.bind(this);
//Updates the canvas
this.redraw = function () {
if (this.points.length > 1) {
stage.clearRect(0, 0, this.canvas.width, this.canvas.height);
stage.lineCap = “round”;
var offsetY = -this.y1;
drawAxes(this.x1, this.x2, this.y1, this.y2, true);
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)
核心竞争力,怎么才能提高呢?
成年人想要改变生活,逆转状态?那就开始学习吧~
万事开头难,但是程序员这一条路坚持几年后发展空间还是非常大的,一切重在坚持。
为了帮助大家更好更高效的准备面试,特别整理了《前端工程师面试手册》电子稿文件。
前端面试题汇总
JavaScript
性能
linux
前端资料汇总
完整版PDF资料免费分享,只需你点赞支持,动动手指点击此处就可领取了。
前端工程师岗位缺口一直很大,符合岗位要求的人越来越少,所以学习前端的小伙伴要注意了,一定要把技能学到扎实,做有含金量的项目,这样在找工作的时候无论遇到什么情况,问题都不会大。
伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!**
[外链图片转存中…(img-yttjTobn-1712562980751)]
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)
核心竞争力,怎么才能提高呢?
成年人想要改变生活,逆转状态?那就开始学习吧~
万事开头难,但是程序员这一条路坚持几年后发展空间还是非常大的,一切重在坚持。
为了帮助大家更好更高效的准备面试,特别整理了《前端工程师面试手册》电子稿文件。
前端面试题汇总
JavaScript
性能
linux
前端资料汇总
完整版PDF资料免费分享,只需你点赞支持,动动手指点击此处就可领取了。
前端工程师岗位缺口一直很大,符合岗位要求的人越来越少,所以学习前端的小伙伴要注意了,一定要把技能学到扎实,做有含金量的项目,这样在找工作的时候无论遇到什么情况,问题都不会大。