常见的js代码封装方法 2023.10.30
- 需求
- 1、js代码封装的优缺点
- 2、js代码封装方式
- 2.1 方式一:function function declarations
- 2.1.1 示例
- 2.2 方式二:class
- 2.2.1 class declarations
- 2.2.2 Class expressions
- 2.3 变量+函数
- 2.4 变量+闭包+匿名函数
- 2.5 闭包函数
- 2.6 变量+闭包+内部变量函数
- 3、匿名函数间接调用执行方法
- 4、小结
需求
许多企业的技术团队和个人开发者为了将自身的技术进行展现,将技术和算法实现的源码进行封装进而以类库和SDK的方式提供给客户使用,也算作一种解决方案,同时封装的类库或SDK
也可对需求方进行量身定制、按需分发、按次调用或按周期计费,进而催生出现代化、便捷化、可插拔、高耦合的服务提供和响应模式。
1、js代码封装的优缺点
正如科技是一把双刃剑,js代码封装自然在带来优势的同时难免会伴随一些劣势,二者之间的平衡取决于供应方和需求方在易用性、高效性、便捷性和版本升级等方面的可接受度
和极限容忍度
。
js代码封装的优点如
下:
(1)代码量变小;
(2)提高js类库代码文件的网络传输速度;
(3)保护代码提供方的知识产权或者劳动成果;
(4)增强对源码的保护,某种程度上可提高安全性。
js代码封装的缺点如下
:
(1)可读性变差;
(2)需进行定期维护或升级更新版本来加入新功能,以此导致用户为使用新功能被动升级;
(3)SDK或类库升级按理应当兼容之前发布的版本;
(4)需提供友好易懂的API调用手册和说明文档,以供用户进行参考。
2、js代码封装方式
通常来说,一个功能或一组属性及方法的封装皆可采用function(函数)和class(类)来实现
,但值得注意的是:函数声明和类声明之间的一个重要区别是,虽然函数可以在定义之前出现的代码中调用,但类必须在构造之前定义。如果小伙伴们对相关的理论知识感兴趣,建议阅读相关规范和官方文档,可参考ECMAScript Language Specification
2.1 方式一:function function declarations
2.1.1 示例
function square(number) {
return number * number;
}
const square = function (number) {
return number * number;
}
const x = square(4); // x gets the value 16
const factorial = function fac(n) {
return n < 2 ? 1 : n * fac(n - 1);
}
console.log(factorial(3))
function map(f, a) {
const result = new Array(a.length);
for (let i = 0; i < a.length; i++) {
result[i] = f(a[i]);
}
return result;
}
const f = function (x) {
return x * x * x;
}
const numbers = [0, 1, 2, 5, 10];
const cube = map(f, numbers);
console.log(cube);
// A nested function example
function getScore() {
const num1 = 2;
const num2 = 3;
function add() {
return `${name} scored ${num1 + num2}`;
}
return add();
}
getScore(); // Returns "Chamakh scored 5"
function addSquares(a, b) {
function square(x) {
return x * x;
}
return square(a) + square(b);
}
const a = addSquares(2, 3); // returns 13
const b = addSquares(3, 4); // returns 25
const c = addSquares(4, 5); // returns 41
function A(x) {
function B(y) {
function C(z) {
console.log(x + y + z);
}
C(3);
}
B(2);
}
A(1); // Logs 6 (which is 1 + 2 + 3)
const pet = function (name) { // The outer function defines a variable called "name"
const getName = function () {
// The inner function has access to the "name" variable of the outer function
return name;
}
return getName; // Return the inner function, thereby exposing it to outer scopes
}
const myPet = pet('Vivie');
myPet(); // Returns "Vivie"
const createPet = function (name) {
let sex;
const pet = {
// setName(newName) is equivalent to setName: function (newName)
// in this context
setName(newName) {
name = newName;
},
getName() {
return name;
},
getSex() {
return sex;
},
setSex(newSex) {
if (typeof newSex === 'string' &&
(newSex.toLowerCase() === 'male' || newSex.toLowerCase() === 'female')) {
sex = newSex;
}
}
};
return pet;
}
const pet = createPet('Vivie');
pet.getName(); // Vivie
pet.setName('Oliver');
pet.setSex('male');
pet.getSex(); // male
pet.getName(); // Oliver
const a = [
'Hydrogen',
'Helium',
'Lithium',
'Beryllium'
];
const a2 = a.map(function(s) { return s.length; });
console.log(a2); // [8, 6, 7, 9]
const a3 = a.map((s) => s.length);
console.log(a3); // [8, 6, 7, 9]
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions
const multiply = new Function('x', 'y', 'return x * y');
function multiply(x, y) {
return x * y;
} // there is no semicolon here
const multiply = function (x, y) {
return x * y;
};
const multiply = function funcName(x, y) {
return x * y;
};
foo(); // Logs "FOO!"
function foo() {
console.log('FOO!');
}
// function declaration
function foo() {}
// function expression
(function bar() {})
// function expression
x = function hello() {}
if (x) {
// function expression
function world() {}
}
// function declaration
function a() {
// function declaration
function b() {}
if (0) {
// function expression
function c() {}
}
}
'use strict';
function f() {
return 1;
}
{
function f() {
return 2;
}
}
f() === 1; // true
// f() === 2 in non-strict mode
// This function returns a string padded with leading zeros
function padZeros(num, totalLen) {
let numStr = num.toString(); // Initialize return value as string
const numZeros = totalLen - numStr.length; // Calculate no. of zeros
for (let i = 1; i <= numZeros; i++) {
numStr = `0${numStr}`;
}
return numStr;
}
if (typeof window.noFunc === 'function') {
// use noFunc()
} else {
// do something else
}
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
static displayName = "Point";
static distance(a, b) {
const dx = a.x - b.x;
const dy = a.y - b.y;
return Math.hypot(dx, dy);
}
}
const p1 = new Point(5, 5);
const p2 = new Point(10, 10);
p1.displayName; // undefined
p1.distance; // undefined
p2.displayName; // undefined
p2.distance; // undefined
console.log(Point.displayName); // "Point"
console.log(Point.distance(p1, p2)); // 7.0710678118654755
2.2 方式二:class
对于一个class而言,constructor有且仅有一个,
Static initialization blocks
Prototype methods
2.2.1 class declarations
class Rectangle {
constructor(height, width) {
this.height = height;
this.width = width;
}
}
class Rectangle {
height = 0;
width;
constructor(height, width) {
this.height = height;
this.width = width;
}
}
class Rectangle {
#height = 0;
#width;
constructor(height, width) {
this.#height = height;
this.#width = width;
}
}
class Polygon {
constructor(...sides) {
this.sides = sides;
}
// Method
*getSides() {
for (const side of this.sides) {
yield side;
}
}
}
const pentagon = new Polygon(1,2,3,4,5);
console.log([...pentagon.getSides()]); // [1,2,3,4,5]
2.2.2 Class expressions
// unnamed
let Rectangle = class {
constructor(height, width) {
this.height = height;
this.width = width;
}
};
console.log(Rectangle.name); // "Rectangle"
// named
Rectangle = class Rectangle2 {
constructor(height, width) {
this.height = height;
this.width = width;
}
};
console.log(Rectangle.name); // "Rectangle2"
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a noise.`);
}
}
class Dog extends Animal {
constructor(name) {
super(name); // call the super class constructor and pass in the name parameter
}
speak() {
console.log(`${this.name} barks.`);
}
}
const d = new Dog('Mitzie');
d.speak(); // Mitzie barks.
function Animal(name) {
this.name = name;
}
Animal.prototype.speak = function () {
console.log(`${this.name} makes a noise.`);
}
class Dog extends Animal {
speak() {
console.log(`${this.name} barks.`);
}
}
const d = new Dog('Mitzie');
d.speak(); // Mitzie barks.
const Animal = {
speak() {
console.log(`${this.name} makes a noise.`);
}
};
class Dog {
constructor(name) {
this.name = name;
}
}
// If you do not do this you will get a TypeError when you invoke speak
Object.setPrototypeOf(Dog.prototype, Animal);
const d = new Dog('Mitzie');
d.speak(); // Mitzie makes a noise.
class Cat {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a noise.`);
}
}
class Lion extends Cat {
speak() {
super.speak();
console.log(`${this.name} roars.`);
}
}
const l = new Lion('Fuzzy');
l.speak();
// Fuzzy makes a noise.
// Fuzzy roars.
2.3 变量+函数
var r = function () {
function e(e, t) {
for (var i = 0; i < t.length; i++) {
var a = t[i]; a.enumerable = a.enumerable || !1, a.configurable = !0, "value" in a && (a.writable = !0),
Object.defineProperty(e, a.key, a)
}
}
return function (t, i, a) {
return i && e(t.prototype, i), a && e(t, a), t
}
}();
Cesium.ViewShed3D = function () {
function e(t, i) {
n(this, e), t && (i || (i = {}),
this.viewer = t,
this.cameraPosition = Cesium.defaultValue(i.cameraPosition, c.cameraPosition),
this.viewPosition = Cesium.defaultValue(i.viewPosition, c.viewPosition),
this._horizontalAngle = Cesium.defaultValue(i.horizontalAngle, c.horizontalAngle),
this._verticalAngle = Cesium.defaultValue(i.verticalAngle, c.verticalAngle),
this._visibleAreaColor = Cesium.defaultValue(i.visibleAreaColor, c.visibleAreaColor),
this._hiddenAreaColor = Cesium.defaultValue(i.hiddenAreaColor, c.hiddenAreaColor),
this._alpha = Cesium.defaultValue(i.alpha, c.alpha),
this._distance = Cesium.defaultValue(i.distance, c.distance),
this._frustum = Cesium.defaultValue(i.frustum, c.frustum),
this.calback = i.calback,
this.cameraPosition && this.viewPosition ? (this._addToScene(), this.calback && this.calback()) : this._bindMourseEvent())
}
return r(e, [{
key: "_bindMourseEvent",
value: function () {
var e = this,
t = this.viewer,
i = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
i.setInputAction(function (i) {
var a = Cesium.getCurrentMousePosition(t.scene, i.position);
a && (e.cameraPosition ? e.cameraPosition && !e.viewPosition && (e.viewPosition = a,
e._addToScene(), e._unbindMourseEvent(), e.calback && e.calback()) : e.cameraPosition = a)
}, Cesium.ScreenSpaceEventType.LEFT_CLICK),
i.setInputAction(function (i) {
var a = Cesium.getCurrentMousePosition(t.scene, i.endPosition);
if (a) {
var n = e.cameraPosition; n && (e.frustumQuaternion = e.getFrustumQuaternion(n, a),
e.distance = Number(Cesium.Cartesian3.distance(n, a).toFixed(1)))
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE),
this._handler = i
}
}, {
key: "_unbindMourseEvent",
value: function () {
null != this._handler && (this._handler.destroy(), delete this._handler)
}
},
2.4 变量+闭包+匿名函数
//获取高程
var TerrainToolCopy = (
function () {
var terrainLevel = 14;//数据等级14
function _() {
}
//传入lonlat数组 角度制的lon lat
_.LonlatPointsTerrainData = function (terrainProvider,lonlats, callback) {
var pointArrInput = [];
for (var i = 0; i < lonlats.length; i++) {
pointArrInput.push(Cesium.Cartographic.fromDegrees(lonlats[i].lon, lonlats[i].lat));
}
var promise = Cesium.sampleTerrain(terrainProvider, terrainLevel, pointArrInput);//pointArrInput
Cesium.when(promise, function (updatedPositions) {
callback(updatedPositions);
});
};
//传入Cartographic类型数组 弧度制经纬度
_.CartographicPointsTerrainData = function (terrainProvider,Cartographics, callback) {
if (Cartographics.length && Cartographics.length > 0) { } else { return; }
var promise = Cesium.sampleTerrain(terrainProvider, terrainLevel, Cartographics);//pointArrInput
Cesium.when(promise, function (updatedPositions) {
callback(updatedPositions);
});
};
return _;
}
)();
2.5 闭包函数
(function () {
function n(t, e) {
e = e || {},
r = t.scene.globe.ellipsoid,
this._geometry = null,
this._angle = e.angle,
this._radius = e.radius ? e.radius : 5,
this._position = e.position,
this._rotation = e.rotation ? e.rotation : {
heading: 0,
pitch: 0,
roll: 0
},
this._trackedEntity = e.trackedEntity,
this.defaultColor = e.color ? e.color : Cesium.Color.YELLOW,
this.defaultLineColor = e.lineColor ? e.lineColor : this.defaultColor,
this._show = Cesium.defaultValue(e.show, !0),
this._outline = Cesium.defaultValue(e.outline, !1),
this._topShow = Cesium.defaultValue(e.top, !0),
this._topOutline = Cesium.defaultValue(e.topOutline, !0),
this._modelMatrix = Cesium.Matrix4.clone(Cesium.Matrix4.IDENTITY),
this._quaternion = new Cesium.Quaternion,
this._translation = new Cesium.Cartesian3,
this._scale = new Cesium.Cartesian3(1, 1, 1),
this._matrix = new Cesium.Matrix4,
this._inverseMatrix = new Cesium.Matrix4,
this._positionCartographic = new Cesium.Cartographic,
this._positionCartesian = null,
this._drawCommands = [],
this._outlinePositions = [],
this.viewer = t,
this.viewer.scene.primitives.add(this),
this.updateGeometry(),
this._groundArea = Cesium.defaultValue(e.groundArea, !1),
this.addGroundAreaEntity(this._groundArea)
}
Object.defineProperty(Cesium, "__esModule", {
value: !0
}),
Cesium.RadarPrimitive = void 0;
var r;
Object.defineProperties(n.prototype, {
trackedEntity: {
get: function () {
return this._trackedEntity
},
set: function (t) {
this._trackedEntity = t
}
},
color: {
get: function () {
return this.defaultColor
},
set: function (t) {
this.defaultColor = t
}
},
lineColor: {
get: function () {
return this.defaultLineColor
},
set: function (t) {
this.defaultLineColor = t
}
},
show: {
get: function () {
return this._show
},
set: function (t) {
this._show = t
}
},
outline: {
get: function () {
return this._outline
},
set: function (t) {
this._outline = t, this.updateGeometry()
}
},
top: {
get: function () {
return this._topShow
},
set: function (t) {
this._topShow = t, this.updateGeometry()
}
},
topOutline: {
get: function () {
return this._topOutline
},
set: function (t) {
this._topOutline = t, this.updateGeometry()
}
},
groundArea: {
get: function () {
return this._groundArea
},
set: function (t) {
this._groundArea = t, this.addGroundAreaEntity(this._groundArea)
}
},
angle: {
get: function () {
return this._angle
},
set: function (t) {
this._angle = t, this.updateGroundCircleRadius(), this.updateGeometry()
}
},
radius: {
get: function () {
return this._radius
},
set: function (t) {
this._radius = t, this.updateGroundCircleRadius(), this.updateGeometry()
}
},
heading: {
get: function () {
return this._rotation.heading
},
set: function (t) {
this._rotation.heading = t
}
},
pitch: {
get: function () {
return this._rotation.pitch
},
set: function (t) {
this._rotation.pitch = t
}
},
roll: {
get: function () {
return this._rotation.roll
},
set: function (t) {
this._rotation.roll = t
}
},
position: {
get: function () {
return this._position
}, set: function (t) {
this._position = t
}
}
}),
n.prototype.updateGroundCircleRadius = function () {
this._ground_radius = this._radius * Math.cos(Cesium.Math.toRadians(this._angle))
},
n.prototype.addGroundAreaEntity = function (t) {
if (t && !this.groundAreaEntity) {
var e = this;
this.updateGroundCircleRadius(),
this.groundAreaEntity = viewer.entities.add({
position: this._position,
ellipse: {
show: 0 === this._rotation.pitch && 0 === this._rotation.roll,
semiMinorAxis: new Cesium.CallbackProperty(function (t) {
return e._ground_radius
}, !1),
semiMajorAxis: new Cesium.CallbackProperty(function (t) {
return e._ground_radius
}, !1),
material: this.defaultColor
},
polyline: {
show: this._trackedEntityPosition && (0 !== this._rotation.pitch || 0 !== this._rotation.roll),
positions: new Cesium.CallbackProperty(function (t) {
return e._trackedEntityPosition ? Cesium.Cartesian3.distance(e._position, e._trackedEntityPosition) > e._radius ? [] : [e._position, e._trackedEntityPosition] : []
}, !1),
followSurface: !1,
material: new Cesium.PolylineDashMaterialProperty({
color: Cesium.Color.CYAN
}),
width: 1
}
})
}
};
var l = new Cesium.Cartesian3;
n.prototype.computeMatrix = function (t, e) {
if (this._positionCartesian || (this._positionCartesian = new Cesium.Cartesian3), this.position instanceof Cesium.Cartesian3 ? this._positionCartesian = this.position : "function" == typeof this.position.getValue ? this._positionCartesian = this.position.getValue(t) : this.position._value && this.position._value instanceof Cesium.Cartesian3 && (this._positionCartesian = this.position._value), this._trackedEntity && this._trackedEntity.position) {
var i = this._positionCartesian,
n = Cesium.Property.getValueOrUndefined(this._trackedEntity.position, t, l);
if (n) {
this._trackedEntityPosition = n;
var o = mars3d.matrix.getHeadingPitchRollForLine(i, n, r);
this._rotation.heading = o.heading, this._rotation.pitch = o.pitch, this._rotation.roll = o.roll
}
}
return this._modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(this._positionCartesian, r, this._modelMatrix),
this._positionCartographic = Cesium.Cartographic.fromCartesian(this._positionCartesian, r, this._positionCartographic),
Cesium.Transforms.eastNorthUpToFixedFrame(this._positionCartesian, r, this._modelMatrix),
Cesium.Quaternion.fromHeadingPitchRoll(this._rotation, this._quaternion),
this._matrix = Cesium.Matrix4.fromTranslationQuaternionRotationScale(this._translation, this._quaternion, this._scale, this._matrix),
Cesium.Matrix4.multiplyTransformation(this._modelMatrix, this._matrix, this._matrix),
Cesium.Matrix4.inverseTransformation(this._matrix, this._inverseMatrix),
this._matrix
},
n.prototype.getTopGeometry = function () {
for (var t = this.radius, e = [], i = [], n = [], r = [], o = 90 - parseInt(this.angle), s = o < 1 ? o / 8 : 1, l = 2 * Math.PI / 127, h = 0, d = this.angle; d < 91; d += s) {
var m = Cesium.Math.toRadians(d < 90 ? d : 90);
m = Math.cos(m) * t;
for (var f = [], p = 0; p < 128; p++) {
var c = l * p,
_ = m * Math.cos(c),
g = m * Math.sin(c),
v = Math.sqrt(t * t - _ * _ - g * g);
e.push(_, g, v),
i.push(1, 1),
f.push(h++)
}
r.push(f)
}
for (var d = 1; d < r.length; d++)
for (var p = 1; p < r[d].length; p++) {
var y = r[d - 1][p - 1],
C = r[d][p - 1],
w = r[d][p], x = r[d - 1][p];
n.push(y, C, w),
n.push(y, w, x)
}
e = new Float32Array(e),
n = new Int32Array(n),
i = new Float32Array(i);
var A = {
position: new Cesium.GeometryAttribute({
componentDatatype: Cesium.ComponentDatatype.DOUBLE,
componentsPerAttribute: 3, values: e
}),
st: new Cesium.GeometryAttribute({ componentDatatype: Cesium.ComponentDatatype.FLOAT, componentsPerAttribute: 2, values: i })
},
b = Cesium.BoundingSphere.fromVertices(e),
M = new Cesium.Geometry({
attributes: A,
indices: n,
primitiveType: Cesium.PrimitiveType.TRIANGLES,
boundingSphere: b
});
return (0, Cesium.computeVertexNormals)(M), M
},
n.prototype.getTopOutlineGeometry = function () {
for (var t = this.radius, e = [], i = [], n = [], r = [], o = 90 - parseInt(this.angle), s = o < 1 ? o / 8 : 1, l = 2 * Math.PI / 127, h = 0, d = this.angle; d < 91; d += s) {
var m = Cesium.Math.toRadians(d < 90 ? d : 90);
m = Math.cos(m) * t;
for (var f = [], p = 0; p < 128; p++) {
var c = l * p, _ = m * Math.cos(c), g = m * Math.sin(c), v = Math.sqrt(t * t - _ * _ - g * g);
e.push(_, g, v), i.push(1, 1), f.push(h++)
}
r.push(f)
}
for (var d = 1; d < r.length; d++)
for (var p = 1; p < r[d].length; p++) {
var y = r[d - 1][p - 1], C = r[d][p - 1], w = r[d][p]; r[d - 1][p];
p % 8 == 1 && n.push(y, C), d % 8 == 1 && n.push(C, w)
}
e = new Float32Array(e), n = new Int32Array(n), i = new Float32Array(i);
var x = {
position: new Cesium.GeometryAttribute({
componentDatatype: Cesium.ComponentDatatype.DOUBLE,
componentsPerAttribute: 3,
values: e
}),
st: new Cesium.GeometryAttribute({
componentDatatype: Cesium.ComponentDatatype.FLOAT,
componentsPerAttribute: 2, values: i
})
},
A = Cesium.BoundingSphere.fromVertices(e),
b = new Cesium.Geometry({
attributes: x,
indices: n,
primitiveType: Cesium.PrimitiveType.LINES,
boundingSphere: A
});
return (0, Cesium.computeVertexNormals)(b), b
},
n.prototype.updateGeometry = function () {
this._geometry = Cesium.CylinderGeometry.createGeometry(new Cesium.CylinderGeometry({
topRadius: this._radius * Math.cos(Cesium.Math.toRadians(this.angle)),
bottomRadius: 0,
length: this._radius * Math.sin(Cesium.Math.toRadians(this.angle))
})),
this._topGeometry = this.getTopGeometry(),
this._topOutlineGeometry = this.getTopOutlineGeometry(),
this._outlineGeometry = Cesium.CylinderGeometry.createOutlineGeometry(new Cesium.CylinderGeometry({
topRadius: this._radius * Math.cos(Cesium.Math.toRadians(this.angle)),
bottomRadius: 0,
slices: 128,
length: this._radius * Math.sin(Cesium.Math.toRadians(this.angle))
})),
this._positions = new Float32Array(this._geometry.attributes.position.values.length);
for (var t = 0; t < this._positions.length; t++)this._positions[t] = this._geometry.attributes.position.values[t];
this._drawCommands && this._drawCommands.length && (this._drawCommands.forEach(function (t) {
t.vertexArray = t.vertexArray && t.vertexArray.destroy()
}),
this._drawCommands.splice(0, this._drawCommands.length))
},
n.prototype.update = function (t) {
if (this._show) {
this.computeMatrix(t.time);
t.mode === Cesium.SceneMode.SCENE3D ? (this._geometry.boundingSphere = Cesium.BoundingSphere.fromVertices(this._geometry.attributes.position.values), this._drawCommands && this._drawCommands.length || (this._drawCommands.push(this.createDrawCommand(this._geometry, t)), this._outline && this._drawCommands.push(this.createDrawCommand(this._outlineGeometry, t)), this._topShow && (this._drawCommands.push(this.createDrawCommand(this._topGeometry, t)),
this._topOutline && this._drawCommands.push(this.createDrawCommand(this._topOutlineGeometry, t)))), this._drawCommands.forEach(function (e) { t.commandList.push(e) }), this.groundAreaEntity && (this.groundAreaEntity.ellipse.show = this._groundArea && 0 === this._rotation.pitch && 0 === this._rotation.roll, this.groundAreaEntity.polyline.show = !1)) : (this.groundAreaEntity || this.addGroundAreaEntity(!0), this.groundAreaEntity.ellipse.show = 0 === this._rotation.pitch && 0 === this._rotation.roll, this.groundAreaEntity.polyline.show = this._trackedEntityPosition && (0 !== this._rotation.pitch || 0 !== this._rotation.roll))
}
},
n.prototype.getFragmentShaderSource = function (t) {
return "\nvarying vec3 v_position;\nvarying vec3 v_normal;\nuniform float picked;\nuniform vec4 pickedColor;\nuniform vec4 defaultColor;\nuniform float specular;\nuniform float shininess;\nuniform vec3 emission;\nvarying vec2 v_st;\nuniform bool isLine;\nuniform float glowPower;\nvoid main() {\n vec3 positionToEyeEC = -v_position; \n vec3 normalEC =normalize(v_normal);\n vec4 color=defaultColor;\n if(picked!=0.0){\n color = pickedColor;\n }\n //if(v_st.x<0.5){\n // color.a =0.75-v_st.x; \n //}\n //else {\n // color.a =v_st.x-0.25; \n //}\n czm_material material;\n material.specular = specular;\n material.shininess = shininess;\n material.normal = normalEC;\n material.emission =emission;//vec3(0.2,0.2,0.2);\n material.diffuse = color.rgb ;\n if(isLine){\n material.alpha = 1.0; \n }\n else{\n material.alpha = color.a; \n }\n //float glow = glowPower / abs(v_st.t ) - (glowPower / 0.5); \n // \n //material.emission = max(vec3(glow - 1.0 + color.rgb), color.rgb); \n //if(isLine)\n // material.alpha = clamp(0.0, 1.0, glow) * color.a; \n \n if(v_st.x==0.0){ \n gl_FragColor =color ;\n }else { \n gl_FragColor = czm_phong(normalize(positionToEyeEC), material) ; \n } \n}"
},
n.prototype.getVertexShaderSource = function (t) {
return "\n#ifdef GL_ES\n precision highp float;\n#endif\n\nattribute vec3 position;\nattribute vec2 st;\nattribute vec3 normal;\nuniform mat4 modelViewMatrix;\nuniform mat3 normalMatrix;\nuniform mat4 projectionMatrix;\nvarying vec3 v_position;\nvarying vec3 v_normal;\nvarying vec2 v_st;\n\nvarying vec3 v_light0Direction;\n\nvoid main(void) \n{\n vec4 pos = modelViewMatrix * vec4( position,1.0);\n v_normal = normalMatrix * normal;\n v_st = st;\n v_position = pos.xyz;\n v_light0Direction = mat3( modelViewMatrix) * vec3(1.0,1.0,1.0);\n gl_Position = projectionMatrix * pos;\n}"
},
n.prototype.createDrawCommand = function (t, e, i) {
var n = e.context, r = new Cesium.Cartesian3; Cesium.Matrix4.multiplyByPoint(this._matrix, t.boundingSphere.center, r);
var o = new Cesium.BoundingSphere(r, t.boundingSphere.radius), s = new Cesium.DrawCommand({
modelMatrix: i || this._matrix,
owner: this,
primitiveType: t.primitiveType,
pass: Cesium.Pass.TRANSLUCENT,
boundingVolume: o
}),
u = this, l = Cesium.GeometryPipeline.createAttributeLocations(t);
return s.vertexArray = Cesium.VertexArray.fromGeometry({
context: n,
geometry: t,
attributeLocations: l,
bufferUsage: Cesium.BufferUsage.STATIC_DRAW
}),
s.vertexArray._attributeLocations = l,
s.shaderProgram = Cesium.ShaderProgram.replaceCache({
context: n,
vertexShaderSource: this.getVertexShaderSource(t),
fragmentShaderSource: this.getFragmentShaderSource(t),
attributeLocations: l
}),
s.renderState = Cesium.RenderState.fromCache({
blending: Cesium.BlendingState.ALPHA_BLEND,
depthTest: {
enabled: !0,
func: Cesium.DepthFunction.LESS
},
cull: {
enabled: !1,
face: Cesium.CullFace.BACK
}
}),
s.uniformMap = {}, s.uniformMap.projectionMatrix = function () {
return e.context.uniformState.projection
},
s.uniformMap.modelViewMatrix = function () {
return e.context.uniformState.modelView
},
s.uniformMap.shininess = function () {
return u.shininess || (u.shininess = 0), u.shininess
},
s.uniformMap.emission = function () {
return u.emission || (u.emission = new Cesium.Cartesian3(.2, .2, .2)), u.emission
},
s.uniformMap.specular = function () {
return u.specular || (u.specular = 0), u.specular
},
s.uniformMap.isLine = function () {
return t.primitiveType == Cesium.PrimitiveType.LINES || t.primitiveType == Cesium.PrimitiveType.LINE_STRIP
},
s.uniformMap.defaultColor = function () {
return t.primitiveType == Cesium.PrimitiveType.LINES || t.primitiveType == Cesium.PrimitiveType.LINE_STRIP ? (u.defaultLineColor || (u.defaultLineColor = new Cesium.Color(1, 1, 0, 1)), u.defaultLineColor) : (u.defaultColor || (u.defaultColor = new Cesium.Color(1, 0, 0, 1)), u.defaultColor)
},
s.uniformMap.picked = function () {
return u.picked || (u.picked = 0), u.picked
},
s.uniformMap.pickedColor = function () {
return u.pickedColor || (u.pickedColor = new Cesium.Color(1, 1, 0, 1)), u.pickedColor
},
s.uniformMap.normalMatrix = function () {
return e.context.uniformState.normal
},
s.uniformMap.glowPower = function () {
return .25
},
s
},
n.prototype.remove = function () {
this.viewer.scene.primitives.remove(this), this.groundAreaEntity && this.viewer.entities.remove(this.groundAreaEntity)
},
n.prototype.addToScene = function () {
this.viewer.scene.primitives.add(this), this.groundAreaEntity && this.viewer.entities.add(this.groundAreaEntity)
},
n.prototype.destroy = function (t) {
t && (this.viewer.scene.primitives.remove(this), this.groundAreaEntity && this.viewer.entities.remove(this.groundAreaEntity), this._drawCommands.forEach(function (t) {
t.vertexArray = t.vertexArray && t.vertexArray.destroy()
}), this._drawCommands = [])
},
Cesium.RadarPrimitive = n
})()
2.6 变量+闭包+内部变量函数
var EllipseGeometryLibraryEx = (function () {
var EllipseGeometryLibrary = {};
var rotAxis = new Cesium.Cartesian3();
var tempVec = new Cesium.Cartesian3();
var unitQuat = new Cesium.Quaternion();
var rotMtx = new Cesium.Matrix3();
function pointOnEllipsoid(theta, rotation, northVec, eastVec, aSqr, ab, bSqr, mag, unitPos, result) {
var azimuth = theta + rotation;
Cesium.Cartesian3.multiplyByScalar(eastVec, Math.cos(azimuth), rotAxis);
Cesium.Cartesian3.multiplyByScalar(northVec, Math.sin(azimuth), tempVec);
Cesium.Cartesian3.add(rotAxis, tempVec, rotAxis);
var cosThetaSquared = Math.cos(theta);
cosThetaSquared = cosThetaSquared * cosThetaSquared;
var sinThetaSquared = Math.sin(theta);
sinThetaSquared = sinThetaSquared * sinThetaSquared;
var radius = ab / Math.sqrt(bSqr * cosThetaSquared + aSqr * sinThetaSquared);
var angle = radius / mag;
// Create the quaternion to rotate the position vector to the boundary of the ellipse.
Cesium.Quaternion.fromAxisAngle(rotAxis, angle, unitQuat);
Cesium.Matrix3.fromQuaternion(unitQuat, rotMtx);
Cesium.Matrix3.multiplyByVector(rotMtx, unitPos, result);
Cesium.Cartesian3.normalize(result, result);
Cesium.Cartesian3.multiplyByScalar(result, mag, result);
return result;
}
var scratchCartesian1 = new Cesium.Cartesian3();
var scratchCartesian2 = new Cesium.Cartesian3();
var scratchCartesian3 = new Cesium.Cartesian3();
var scratchNormal = new Cesium.Cartesian3();
/**
* Returns the positions raised to the given heights
* @private
*/
EllipseGeometryLibrary.raisePositionsToHeight = function (positions, options, extrude) {
var ellipsoid = options.ellipsoid;
var height = options.height;
var extrudedHeight = options.extrudedHeight;
var size = (extrude) ? positions.length / 3 * 2 : positions.length / 3;
var finalPositions = new Float64Array(size * 3);
var length = positions.length;
var bottomOffset = (extrude) ? length : 0;
for (var i = 0; i < length; i += 3) {
var i1 = i + 1;
var i2 = i + 2;
var position = Cesium.Cartesian3.fromArray(positions, i, scratchCartesian1);
ellipsoid.scaleToGeodeticSurface(position, position);
var extrudedPosition = Cesium.Cartesian3.clone(position, scratchCartesian2);
var normal = ellipsoid.geodeticSurfaceNormal(position, scratchNormal);
var scaledNormal = Cesium.Cartesian3.multiplyByScalar(normal, height, scratchCartesian3);
Cesium.Cartesian3.add(position, scaledNormal, position);
if (extrude) {
Cesium.Cartesian3.multiplyByScalar(normal, extrudedHeight, scaledNormal);
Cesium.Cartesian3.add(extrudedPosition, scaledNormal, extrudedPosition);
finalPositions[i + bottomOffset] = extrudedPosition.x;
finalPositions[i1 + bottomOffset] = extrudedPosition.y;
finalPositions[i2 + bottomOffset] = extrudedPosition.z;
}
finalPositions[i] = position.x;
finalPositions[i1] = position.y;
finalPositions[i2] = position.z;
}
return finalPositions;
};
var unitPosScratch = new Cesium.Cartesian3();
var eastVecScratch = new Cesium.Cartesian3();
var northVecScratch = new Cesium.Cartesian3();
/**
* options.semiMinorAxis:短半轴
* options.semiMajorAxis:长半轴
* options.rotation:旋转角度 弧度
* options.center:中心点 笛卡尔坐标
* options.granularity:粒度 弧度
addFillPositions:是否插值
addEdgePositions:是否添加端点
* Returns an array of positions that make up the ellipse.
* @private
*/
EllipseGeometryLibrary.computeEllipsePositions = function (options, addEdgePositions) {
var semiMinorAxis = options.semiMinorAxis;
var semiMajorAxis = options.semiMajorAxis;
var rotation = options.rotation;//法线
var center = options.center;
var granularity = options.granularity && (typeof options.granularity === "number") ? options.granularity : (Math.PI / 180.0);// 角度间隔
if (granularity > Math.PI / 12.0) { granularity = Math.PI / 12.0; }
if (granularity < Math.PI / 180.0) { granularity = Math.PI / 180.0; }
var aSqr = semiMinorAxis * semiMinorAxis;
var bSqr = semiMajorAxis * semiMajorAxis;
var ab = semiMajorAxis * semiMinorAxis;
var mag = Cesium.Cartesian3.magnitude(center);//模
var unitPos = Cesium.Cartesian3.normalize(center, unitPosScratch);
var eastVec = Cesium.Cartesian3.cross(Cesium.Cartesian3.UNIT_Z, center, eastVecScratch);
eastVec = Cesium.Cartesian3.normalize(eastVec, eastVec);
var northVec = Cesium.Cartesian3.cross(unitPos, eastVec, northVecScratch);
var numPts = 1 + Math.ceil(Cesium.Math.PI_OVER_TWO / granularity);
var deltaTheta = Cesium.Math.PI_OVER_TWO / (numPts - 1);
var theta = Cesium.Math.PI_OVER_TWO - numPts * deltaTheta;
if (theta < 0.0) {
numPts -= Math.ceil(Math.abs(theta) / deltaTheta);
}
var positions = new Array((numPts + 1) * 3);
var positionsdown = new Array((numPts + 1) * 3);
var positionIndex = 0;
var positionsdownIndex = 0;
var position = scratchCartesian1;
var reflectedPosition = scratchCartesian2;
var outerPositionsLength = (numPts * 4) * 3;
var outerRightIndex = outerPositionsLength - 1;
var outerLeftIndex = 0;
var outerPositions = (addEdgePositions) ? new Array(outerPositionsLength) : undefined;
var i;
var j;
var numInterior;
var t;
var interiorPosition;
theta = Cesium.Math.PI_OVER_TWO;
position = pointOnEllipsoid(theta, rotation, northVec, eastVec, aSqr, ab, bSqr, mag, unitPos, position);
positions[positionIndex++] = position.x;
positions[positionIndex++] = position.y;
positions[positionIndex++] = position.z;
if (addEdgePositions) {
outerPositions[outerRightIndex--] = position.z;
outerPositions[outerRightIndex--] = position.y;
outerPositions[outerRightIndex--] = position.x;
}
theta = Cesium.Math.PI_OVER_TWO - deltaTheta;
for (i = 1; i < numPts + 1; ++i) {
position = pointOnEllipsoid(theta, rotation, northVec, eastVec, aSqr, ab, bSqr, mag, unitPos, position);
reflectedPosition = pointOnEllipsoid(Math.PI - theta, rotation, northVec, eastVec, aSqr, ab, bSqr, mag, unitPos, reflectedPosition);
positionsdown[positionsdownIndex++] = position.x;
positionsdown[positionsdownIndex++] = position.y;
positionsdown[positionsdownIndex++] = position.z;
positions[positionIndex++] = reflectedPosition.x;
positions[positionIndex++] = reflectedPosition.y;
positions[positionIndex++] = reflectedPosition.z;
if (addEdgePositions) {
outerPositions[outerRightIndex--] = position.z;
outerPositions[outerRightIndex--] = position.y;
outerPositions[outerRightIndex--] = position.x;
outerPositions[outerLeftIndex++] = reflectedPosition.x;
outerPositions[outerLeftIndex++] = reflectedPosition.y;
outerPositions[outerLeftIndex++] = reflectedPosition.z;
}
theta = Cesium.Math.PI_OVER_TWO - (i + 1) * deltaTheta;
}
for (i = numPts; i > 1; --i) {
theta = Cesium.Math.PI_OVER_TWO - (i - 1) * deltaTheta;
position = pointOnEllipsoid(-theta, rotation, northVec, eastVec, aSqr, ab, bSqr, mag, unitPos, position);
reflectedPosition = pointOnEllipsoid(theta + Math.PI, rotation, northVec, eastVec, aSqr, ab, bSqr, mag, unitPos, reflectedPosition);
positionsdown[positionsdownIndex++] = position.x;
positionsdown[positionsdownIndex++] = position.y;
positionsdown[positionsdownIndex++] = position.z;
positions[positionIndex++] = reflectedPosition.x;
positions[positionIndex++] = reflectedPosition.y;
positions[positionIndex++] = reflectedPosition.z;
if (addEdgePositions) {
outerPositions[outerRightIndex--] = position.z;
outerPositions[outerRightIndex--] = position.y;
outerPositions[outerRightIndex--] = position.x;
outerPositions[outerLeftIndex++] = reflectedPosition.x;
outerPositions[outerLeftIndex++] = reflectedPosition.y;
outerPositions[outerLeftIndex++] = reflectedPosition.z;
}
}
theta = Cesium.Math.PI_OVER_TWO;
position = pointOnEllipsoid(-theta, rotation, northVec, eastVec, aSqr, ab, bSqr, mag, unitPos, position);
var r = {};
positionsdown[positionsdownIndex++] = position.x;
positionsdown[positionsdownIndex++] = position.y;
positionsdown[positionsdownIndex++] = position.z;
r.positions = positions;
r.positionsdown = positionsdown;
r.numPts = numPts;
if (addEdgePositions) {
outerPositions[outerRightIndex--] = position.z;
outerPositions[outerRightIndex--] = position.y;
outerPositions[outerRightIndex--] = position.x;
r.outerPositions = outerPositions;
}
return r;
};
/**
* options.semiMinorAxis:短半轴
* options.semiMajorAxis:长半轴
* options.rotation:旋转角度 弧度
* options.center:中心点 笛卡尔坐标
* options.granularity:粒度 弧度
* Returns an array of positions that make up the ellipse.
* @private
*/
EllipseGeometryLibrary.computeEllipseEdgePositions = function (options) {
var semiMinorAxis = options.semiMinorAxis;
var semiMajorAxis = options.semiMajorAxis;
var rotation = options.rotation;//法线
var center = options.center;
var granularity = options.granularity && (typeof options.granularity === "number") ? options.granularity : (Math.PI / 180.0);// 角度间隔
if (granularity > Math.PI / 12.0) { granularity = Math.PI / 12.0; }
if (granularity < Math.PI / 180.0) { granularity = Math.PI / 180.0; }
var aSqr = semiMinorAxis * semiMinorAxis;
var bSqr = semiMajorAxis * semiMajorAxis;
var ab = semiMajorAxis * semiMinorAxis;
var mag = Cesium.Cartesian3.magnitude(center);//
var unitPos = Cesium.Cartesian3.normalize(center, unitPosScratch);
var eastVec = Cesium.Cartesian3.cross(Cesium.Cartesian3.UNIT_Z, center, eastVecScratch);
eastVec = Cesium.Cartesian3.normalize(eastVec, eastVec);
var northVec = Cesium.Cartesian3.cross(unitPos, eastVec, northVecScratch);
var numPts = Math.ceil(Cesium.Math.PI * 2 / granularity);
var deltaTheta = granularity;
var theta = 0;
var position = scratchCartesian1;
var i;
var outerIndex = 0;
var outerPositions = [];
for (i = 0; i < numPts; i++) {
theta = i * deltaTheta;
position = pointOnEllipsoid(theta, rotation, northVec, eastVec, aSqr, ab, bSqr, mag, unitPos, position);
outerPositions[outerIndex++] = position.x;
outerPositions[outerIndex++] = position.y;
outerPositions[outerIndex++] = position.z;
}
var r = {};
r.numPts = numPts;
r.outerPositions = outerPositions;
return r;
};
return EllipseGeometryLibrary;
})();
3、匿名函数间接调用执行方法
同时,封装的js代码为了避免用户根据API函数名称搜索或定位代码位置,因此就存在匿名函数来帮助解决这一困扰,匿名函数也称无名函数,顾明思义不需要为函数起名,因此也就具有高隐蔽性、定位难度大、作用域有限、封闭性强等特点,加之匿名函数可层层嵌套,较难捕捉,一定程度上有利于对代码安全的保护。
(function (){console.log('jjg')}())
!function(a,b){console.log(a+b);}('hello','world')
eval('function print(a){console.log(a);}\x20print(`jjg`)')
(function(){console.log('jing_zhong')})()
4、小结
逝者如斯,日月如梭。转眼间已经接触FrontEnd
和WebGIS
开发一年有余,与许多技术娴熟、经验丰富的前辈接触,深表敬佩,感慨颇丰,在面对复杂、繁琐、大型的实战项目页面应用开发任务时,除了从互联网上寻找相关资料和博客文章中借鉴代码示例,更多地从他们的身上学到了面对问题时的沉着冷静、从容不迫、临危不惧、化难为易、深入浅出、巧妙应对,其实许多挑战往往都能够迎刃而解,善于求助是强者的行为,开放平等的交流能够积极促进对话,进而相互探讨、理解、共同思考,众人拾柴火焰高,独乐乐不如众乐乐,积极地分享知识、技术、经验和技巧给志同道合、兴趣相投的好友,实乃人生一大乐事,正所谓知音难觅,知己难求
,在当下物欲横流、飞速发展的社会,希望每个人都能寻找到自己的佳音,互相扶持,相伴一生。(注:尽管本文介绍自己所看到的js封装的几种方法,旨在与广大开发者、技术爱好者共同探讨分享,严禁随意用于商业用途!!!作者本人从内心深处热爱开源、力促开源,希望为开源贡献绵薄之力,封闭必然导致落后自大,开源代表开放合作,知识共享,伟大的人类同处地球村,是一个命运共同体,应该通力合作,优势互补,取长补短,共同进步,不断推动人类的进步与繁荣)
与此同时,不免感慨,不禁赞叹:正如高手在民间一样,真正的强者从来都会大隐于市,不抱怨环境,逆境生长,谦虚低调,更加善于从文学、艺术、歌舞等身边事物汲取精神养料,陶冶情操,追求乐观豁达、自然洒脱的心境,敢于接受自我的渺小和平凡。天地之大,万类霜天竞自由,适者生存,物竞天择,无外乎天外有天、山外有山、人外有人,愿自己能够不忘初心,坚定脚步,砥砺前行,始终坚信美好新鲜的事物即将发生,永远感恩父母、热爱生活、热爱人民、热爱世界。